Re: [ovs-dev] [OVN Patch v14 1/3] ovn-libs: Add support for parallel processing

2021-02-18 Thread Anton Ivanov

On 18/02/2021 22:36, Mark Michelson wrote:

Hi Anton, in short:

Acked-by: Mark Michelson 

I think this can go in as-is. My only question is with regards to how 
dp_groups are handled. The current patch makes it so that when 
dp_groups are used, we parallelize the work. However, instead of each 
thread creating discrete segments of lflows, each thread shares a 
reference to the same large lflow hmap. This means the threads have to 
lock the pertinent hash row each time they add a lflow to the hmap. 
This makes sense since the entire lflow hmap needs to be taken into 
account when determining if a flow is repeated between different 
datapaths.


I'm curious if this contention might result in poorer parallization 
speedup.



It does. According to Newman's results the speedup is ~ 2 times instead 
of 4+



Without having done any profiling, my assumption is that this 
shouldn't perform worse than single-threaded code, but that it likely 
isn't performing that much better either.


See above.

Because this isn't actively *harming* performance, that's why I went 
ahead and acked the patch series.


Once we have run some performance tests, it would be worth determining 
if the algorithm used for dp_groups could be improved. I have a couple 
of thoughts:


1) It might just make sense to disable parallelization when dp_groups 
are enabled. This certainly wouldn't help performance, but it would 
simplify northd somewhat. This might be an OK tradeoff if the 
performance improvement from parallelization with dp_groups is 
insignificant.


Actually, it looks like it is still faster if you have at least 8 
threads to throw at it.




2) We could fully parallelize lflow table creation just like we do 
when dp_groups are disabled: split the lflow hmap into segments for 
each worker to fill in, and then merge them together once all threads 
are complete. Then after merging, we could iterate over the completed 
lflow hmap and determine the dp_groups at that point, rather than when 
inserting the lflow into the hmap. This extra hmap traversal might 
slow things down some, but uncontended parallelization could more than 
offset that cost.


I would suggest leaving it as is. It does not lock full table - it locks 
"hash rows". So the contention is not as bad as one would expect and it 
still provides a reasonable gain.




What do you think about these ideas? I bring them up because OVN is 
trending towards eventually having dp_groups enabled and no longer 
being disable-able.


On 2/12/21 9:49 AM, Anton Ivanov wrote:

This adds a set of functions and macros intended to process
hashes in parallel.

The principles of operation are documented in the fasthmap.h

If these one day go into the OVS tree, the OVS tree versions
would be used in preference.

Signed-off-by: Anton Ivanov 
---
  lib/automake.mk |   2 +
  lib/ovn-parallel-hmap.c | 455 
  lib/ovn-parallel-hmap.h | 285 +
  3 files changed, 742 insertions(+)
  create mode 100644 lib/ovn-parallel-hmap.c
  create mode 100644 lib/ovn-parallel-hmap.h

diff --git a/lib/automake.mk b/lib/automake.mk
index 250c7aefa..781be2109 100644
--- a/lib/automake.mk
+++ b/lib/automake.mk
@@ -13,6 +13,8 @@ lib_libovn_la_SOURCES = \
  lib/expr.c \
  lib/extend-table.h \
  lib/extend-table.c \
+    lib/ovn-parallel-hmap.h \
+    lib/ovn-parallel-hmap.c \
  lib/ip-mcast-index.c \
  lib/ip-mcast-index.h \
  lib/mcast-group-index.c \
diff --git a/lib/ovn-parallel-hmap.c b/lib/ovn-parallel-hmap.c
new file mode 100644
index 0..06aa95aba
--- /dev/null
+++ b/lib/ovn-parallel-hmap.c
@@ -0,0 +1,455 @@
+/*
+ * Copyright (c) 2020 Red Hat, Inc.
+ * Copyright (c) 2008, 2009, 2010, 2012, 2013, 2015, 2019 Nicira, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 
implied.

+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include "fatal-signal.h"
+#include "util.h"
+#include "openvswitch/vlog.h"
+#include "openvswitch/hmap.h"
+#include "openvswitch/thread.h"
+#include "ovn-parallel-hmap.h"
+#include "ovs-atomic.h"
+#include "ovs-thread.h"
+#include "ovs-numa.h"
+#include "random.h"
+
+VLOG_DEFINE_THIS_MODULE(ovn_parallel_hmap);
+
+#ifndef OVS_HAS_PARALLEL_HMAP
+
+#define WORKER_SEM_NAME "%x-%p-%x"
+#define MAIN_SEM_NAME "%x-%p-main"
+
+/* These are accessed under mutex inside add_worker_pool().
+ * They do not need to be atomic.
+ */
+
+static 

Re: [ovs-dev] [PATCH ovn v3] northd: Provide the Gateway router option 'lb_force_snat_ip' to take router port ips.

2021-02-18 Thread Numan Siddique
On Fri, Feb 19, 2021 at 12:53 AM Mark Gray  wrote:
>
> On 18/02/2021 19:00, num...@ovn.org wrote:
> > From: Numan Siddique 
> >
> > When a Gateway router is configured with a load balancer
> > and it is also configured with options:lb_force_snat_ip=,
> > OVN after load balancing the destination IP to one of the
> > backend also does a NAT on the source ip with the
> > lb_force_snat_ip if the packet is destined to a load balancer
> > VIP.
> >
> > There is a problem with the snat of source ip to 'lb_force_snat_ip'
> > in one particular usecase.  When the packet enters the Gateway router
> > from a provider logical switch destined to the load balancer VIP,
> > then it is first load balanced to one of the backend and then
> > the source ip is snatted to 'lb_force_snat_ip'.  If the chosen
> > backend is reachable via the provider logical switch, then the
> > packet is hairpinned back and it may hit the wire with
> > the source ip 'lb_force_snat_ip'.  If 'lb_force_snat_ip' happens
> > to be an OVN internal IP then the packet may be dropped.
> >
> > This patch addresses this issue by providing the option to
> > set the option - 'lb_force_snat_ip=router_ip'.  If 'router_ip'
> > is set, then OVN will snat the load balanced packet to the
> > router ip of the logical router port which is chosen as 'outport'
> > in lr_in_ip_routing stage.
> >
> > Example.
> >
> > If the gateway router is
> >
> > ovn-nbctl show lr0
> > router 68f20092-5563-44b8-9ccb-b11de3e3a66c (lr0)
> > port lr0-sw0
> > mac: "00:00:00:00:ff:01"
> > networks: ["10.0.0.1/24"]
> > port lr0-public
> > mac: "00:00:20:20:12:13"
> > networks: ["172.168.0.100/24"]
> >
> > Then the below logical flows are added if 'lb_force_snat_ip'
> > is configured to 'router_ip'.
> >
> > table=1 (lr_out_snat), priority=110
> >match=(flags.force_snat_for_lb == 1 && ip4 && outport == "lr0-public"),
> >action=(ct_snat(172.168.0.100);)
> >
> > table=1 (lr_out_snat), priority=110
> >match=(flags.force_snat_for_lb == 1 && ip4 && outport == "lr0-sw0")
> >action=(ct_snat(10.0.0.1);)
> >
> > For the above described scenario, the packet will have source ip as
> > 172.168.0.100 which belongs to the provider logical switch CIDR.
> >
> > Reported-by: Tim Rozet 
> > Signed-off-by: Numan Siddique 
> > ---
> >  northd/ovn-northd.8.xml | 35 
> >  northd/ovn-northd.c | 91 +
> >  ovn-nb.xml  | 33 ++-
> >  tests/ovn-northd.at | 79 +++
> >  4 files changed, 220 insertions(+), 18 deletions(-)
> >
> > diff --git a/northd/ovn-northd.8.xml b/northd/ovn-northd.8.xml
> > index 2f8b4e8c30..1d8f5edee1 100644
> > --- a/northd/ovn-northd.8.xml
> > +++ b/northd/ovn-northd.8.xml
> > @@ -3654,6 +3654,32 @@ nd_ns {
> >flags.force_snat_for_dnat == 1  ip with an
> >action ct_snat(B);.
> >  
> > +  
> > +
> > +  
> > +
> > +  If the Gateway router in the OVN Northbound database has been
> > +  configured to force SNAT a packet (that has been previously
> > +  load-balanced) using router IP (i.e  > +  table="Logical_Router"/>:lb_force_snat_ip=router_ip), then for
> > +  each logical router port P attached to the Gateway
> > +  router, a priority-110 flow matches
> > +  flags.force_snat_for_lb == 1  outport == 
> > P
> > +   with an action ct_snat(R);
> > +  where R is the IP configured on the router port.
> > +  If R is an IPv4 address then the match will also
> > +  include ip4 and if it is an IPv6 address, then the
> > +  match will also include ip6.
> > +
> > +
> > +
> > +  If the logical router port P is configured with 
> > multiple
> > +  IPv4 and multiple IPv6 addresses, only the first IPv4 and first 
> > IPv6
> > +  address is considered.
> > +
> > +  
> > +
> > +  
> >  
> >If the Gateway router in the OVN Northbound database has been
> >configured to force SNAT a packet (that has been previously
> > @@ -3661,6 +3687,9 @@ nd_ns {
> >flags.force_snat_for_lb == 1  ip with an
> >action ct_snat(B);.
> >  
> > +  
> > +
> > +  
> >  
> >For each configuration in the OVN Northbound database, that asks
> >to change the source IP address of a packet from an IP address of
> > @@ -3674,14 +3703,18 @@ nd_ns {
> >options, then the action would be ip4/6.src=
> >(B).
> >  
> > +  
> >
> > +  
> >  
> >If the NAT rule has allowed_ext_ips configured, then
> >there is an additional match ip4.dst == 
> > allowed_ext_ips
> >. Similarly, for IPV6, match would be ip6.dst 
> > ==
> >allowed_ext_ips.
> >  
> > +  
> >
> > +  
> >  
> > 

Re: [ovs-dev] [PATCHv2] connmgr: Check nullptr inside ofmonitor_report()

2021-02-18 Thread 贺鹏
Hi,

Looks like this bug is caused by violating the fact that if a rule is
referenced, the related ofproto should not be destroyed.

If so, I have a patch that also fixes the problem, not sure if this helps.

http://patchwork.ozlabs.org/project/openvswitch/patch/20200717015041.82746-1-hepeng.0...@bytedance.com/

William Tu  于2021年2月19日周五 上午8:10写道:
>
> On Wed, Feb 17, 2021 at 1:09 PM Yifeng Sun  wrote:
> >
> > ovs-vswitchd could crash under these circumstances:
> > 1. When one bridge is being destroyed, ofproto_destroy() is called and
> > connmgr pointer of its ofproto struct is nullified. This ofproto struct is
> > deallocated through 'ovsrcu_postpone(ofproto_destroy_defer__, p);'.
> > 2. Before RCU enters quiesce state to actually free this ofproto struct,
> > revalidator thread calls udpif_revalidator(), which could handle
> > a learn flow and calls ofproto_flow_mod_learn(), it later calls
> > ofmonitor_report() and ofproto struct's connmgr pointer is accessed.
> >
> > The crash stack trace is shown below:
> >
> > 0  ofmonitor_report (mgr=0x0, rule=rule@entry=0x7fa4ac067c30, 
> > event=event@entry=NXFME_ADDED,
> > reason=reason@entry=OFPRR_IDLE_TIMEOUT, abbrev_ofconn=0x0, 
> > abbrev_xid=0, old_actions=old_actions@entry=0x0)
> > at ofproto/connmgr.c:2160
> > 1  0x7fa4d6803495 in add_flow_finish (ofproto=0x55d9075d4ab0, 
> > ofm=, req=req@entry=0x0)
> > at ofproto/ofproto.c:5221
> > 2  0x7fa4d68036af in modify_flows_finish (req=0x0, ofm=0x7fa4980753f0, 
> > ofproto=0x55d9075d4ab0)
> > at ofproto/ofproto.c:5823
> > 3  ofproto_flow_mod_finish (ofproto=0x55d9075d4ab0, 
> > ofm=ofm@entry=0x7fa4980753f0, req=req@entry=0x0)
> > at ofproto/ofproto.c:8088
> > 4  0x7fa4d680372d in ofproto_flow_mod_learn_finish 
> > (ofm=ofm@entry=0x7fa4980753f0,
> > orig_ofproto=orig_ofproto@entry=0x0) at ofproto/ofproto.c:5439
> > 5  0x7fa4d68072f9 in ofproto_flow_mod_learn (ofm=0x7fa4980753f0, 
> > keep_ref=keep_ref@entry=true,
> > limit=, below_limitp=below_limitp@entry=0x0) at 
> > ofproto/ofproto.c:5499
> > 6  0x7fa4d6835d33 in xlate_push_stats_entry (entry=0x7fa498012448, 
> > stats=stats@entry=0x7fa4d2701a10,
> > offloaded=offloaded@entry=false) at 
> > ofproto/ofproto-dpif-xlate-cache.c:127
> > 7  0x7fa4d6835e3a in xlate_push_stats (xcache=, 
> > stats=stats@entry=0x7fa4d2701a10,
> > offloaded=offloaded@entry=false) at 
> > ofproto/ofproto-dpif-xlate-cache.c:181
> > 8  0x7fa4d6822046 in revalidate_ukey (udpif=udpif@entry=0x55d90760b240, 
> > ukey=ukey@entry=0x7fa4b0191660,
> > stats=stats@entry=0x7fa4d2705118, 
> > odp_actions=odp_actions@entry=0x7fa4d2701b50,
> > reval_seq=reval_seq@entry=5655486242, 
> > recircs=recircs@entry=0x7fa4d2701b40, offloaded=false)
> > at ofproto/ofproto-dpif-upcall.c:2294
> > 9  0x7fa4d6825aee in revalidate (revalidator=0x55d90769dd00) at 
> > ofproto/ofproto-dpif-upcall.c:2683
> > 10 0x7fa4d6825cf3 in udpif_revalidator (arg=0x55d90769dd00) at 
> > ofproto/ofproto-dpif-upcall.c:936
> > 11 0x7fa4d6259c9f in ovsthread_wrapper (aux_=) at 
> > lib/ovs-thread.c:423
> > 12 0x7fa4d582cea5 in start_thread () from /usr/lib64/libpthread.so.0
> > 13 0x7fa4d504b96d in clone () from /usr/lib64/libc.so.6
> >
> > At the time of crash, the involved ofproto was already deallocated:
> >
> > (gdb) print *ofproto
> > $1 = ..., name = 0x55d907602820 "nsx-managed", ..., ports = {...,
> > one = 0x0, mask = 63, n = 0}, ..., connmgr = 0x0, ...
> >
> > This patch fixes it.
> >
> > VMware-BZ: #2700626
> > Signed-off-by: Yifeng Sun 
> > ---
> > v1->v2: Add check for ofmonitor_flush, thanks William.
> >
>
> LGTM, thanks.
> Acked-by: William Tu < u9012...@gmail.com>
>
> CC Ilya and Ben to see if any comments.
>
> I feel this kind of RCU issue is hard to find out, and
> existing tools such as addressSanitizer are usually
> not helpful.
>
> William
>
> >  ofproto/connmgr.c | 6 +-
> >  1 file changed, 5 insertions(+), 1 deletion(-)
> >
> > diff --git a/ofproto/connmgr.c b/ofproto/connmgr.c
> > index 9c5c633b4171..fa8f6cd0e83a 100644
> > --- a/ofproto/connmgr.c
> > +++ b/ofproto/connmgr.c
> > @@ -2140,7 +2140,7 @@ ofmonitor_report(struct connmgr *mgr, struct rule 
> > *rule,
> >   const struct rule_actions *old_actions)
> >  OVS_REQUIRES(ofproto_mutex)
> >  {
> > -if (rule_is_hidden(rule)) {
> > +if (!mgr || rule_is_hidden(rule)) {
> >  return;
> >  }
> >
> > @@ -2244,6 +2244,10 @@ ofmonitor_flush(struct connmgr *mgr)
> >  {
> >  struct ofconn *ofconn;
> >
> > +if (!mgr) {
> > +return;
> > +}
> > +
> >  LIST_FOR_EACH (ofconn, connmgr_node, >conns) {
> >  struct rconn_packet_counter *counter = ofconn->monitor_counter;
> >
> > --
> > 2.7.4
> >
> > ___
> > dev mailing list
> > d...@openvswitch.org
> > https://mail.openvswitch.org/mailman/listinfo/ovs-dev
> ___
> dev 

Re: [ovs-dev] [PATCH ovn 0/6] MAC learning support in OVN.

2021-02-18 Thread Mark Michelson

Aside from the comments on patch 1,

Acked-by: Mark Michelson 


On 2/5/21 1:56 AM, num...@ovn.org wrote:

From: Numan Siddique 

This series adds the support to learn the macs seen on logical port
VIF's whose port security is disabled and 'unknown' address set.

A new table - FDB is added in Southboud database to store the
port-to-mac mappings.

The first patch is a small refactor and moves the mac_binding related
code from pinctrl.c to a separate file - mac-learn.c. pinctrl.c still
writes the learnt mac_bindings to the MAC_Binding table.

The remaining patches actually adds the mac learning support.

The main usecase of this patch series is to stop flooding of the packet
to all the logical ports which accept unknown destinations once the
mac is learnt from such ports.  This patch excludes learning the macs
from the localnet ports as this could cause lot of FDB entries since
such ports can receive the broad cast traffic fron the physical network.

Numan Siddique (6):
   controller: Split mac learning code to a separate file.
   MAC learning: Add a new FDB table in southbound db.
   MAC learning: Add new actions - put_fdb, get_fdb and lookup_fdb.
   controller: MAC learning: Add OF rules for the FDB entries.
   northd: MAC learning: Add logical flows for fdb.
   northd: Cleanup stale FDB entries.

  controller/automake.mk   |   5 +-
  controller/lflow.c   | 110 +++
  controller/lflow.h   |  13 +-
  controller/mac-learn.c   | 180 +++
  controller/mac-learn.h   |  66 
  controller/ovn-controller.c  |  32 +-
  controller/pinctrl.c | 220 +-
  controller/pinctrl.h |   1 +
  include/ovn/actions.h|  33 ++
  include/ovn/logical-fields.h |   4 +
  lib/actions.c| 176 +++
  lib/ovn-util.c   |  20 +-
  lib/ovn-util.h   |   4 +
  northd/ovn-northd.8.xml  | 162 --
  northd/ovn-northd.c  | 136 +++--
  ovn-sb.ovsschema |  19 +-
  ovn-sb.xml   |  86 ++
  tests/ovn-northd.at  |  92 +-
  tests/ovn.at | 575 ---
  tests/test-ovn.c |   2 +
  utilities/ovn-trace.c| 145 -
  21 files changed, 1887 insertions(+), 194 deletions(-)
  create mode 100644 controller/mac-learn.c
  create mode 100644 controller/mac-learn.h



___
dev mailing list
d...@openvswitch.org
https://mail.openvswitch.org/mailman/listinfo/ovs-dev


Re: [ovs-dev] [PATCH ovn] northd: Fix ha_chassis_group txn error for external ports.

2021-02-18 Thread Mark Michelson

Acked-by: Mark Michelson 

On 2/12/21 2:21 AM, num...@ovn.org wrote:

From: Numan Siddique 

If an external logical port 'sw0-p1' is associated with an
ha_chassis_group and later CMS runs a command to clear the
ha_chassis_group and set the type to normal in the same
transaction, i.e

ovn-nbctl clear logical_switch_port sw0-p1 ha_chassis_group -- \
set logical_switch_port sw0-p1 'type=""'

then, ovn-northd goes into a continous loop trying to delete the
ha_chassis_group in SB DB .  ovn-northd doesn't clear the
ha_chassis_group of the port binding sw0-p1 in the SB DB and
hence the constraint violation is seen.

This issue is seen when lport sw0-p1 is the only one referencing
the ha_chassis_group in SB DB.  This patch fixes this issue.

Reported-at: https://bugzilla.redhat.com/show_bug.cgi?id=1927369
Reported-by: Jakub Libosvar 
Signed-off-by: Numan Siddique 
---
  northd/ovn-northd.c |  6 ++
  tests/ovn-northd.at | 47 ++---
  2 files changed, 50 insertions(+), 3 deletions(-)

diff --git a/northd/ovn-northd.c b/northd/ovn-northd.c
index b2b5f6a1b..83af4464c 100644
--- a/northd/ovn-northd.c
+++ b/northd/ovn-northd.c
@@ -2976,6 +2976,12 @@ ovn_port_update_sbrec(struct northd_context *ctx,
  } else {
  sbrec_port_binding_set_ha_chassis_group(op->sb, NULL);
  }
+} else if (op->sb->ha_chassis_group) {
+/* Clear the port bindings ha_chassis_group if the type is
+ * not external and if this column is set.  This can happen
+ * when an external port is reset to type normal and
+ * ha_chassis_group cleared in the same transaction. */
+sbrec_port_binding_set_ha_chassis_group(op->sb, NULL);
  }
  } else {
  const char *chassis = NULL;
diff --git a/tests/ovn-northd.at b/tests/ovn-northd.at
index 64a788067..5af77470a 100644
--- a/tests/ovn-northd.at
+++ b/tests/ovn-northd.at
@@ -605,11 +605,12 @@ wait_row_count Port_Binding 0 logical_port=sw0-pext1 
'chassis!=[[]]'
  wait_row_count HA_Chassis_Group 1 name=hagrp1
  wait_row_count HA_Chassis 3
  
-# Clear ha_chassis_group for sw0-pext2

-ovn-nbctl --wait=sb clear logical_switch_port sw0-pext2 ha_chassis_group
+AS_BOX([Clear ha_chassis_group for sw0-pext2 and reset port type to normal in 
the same txn])
  
-wait_row_count Port_Binding 0 logical_port=sw0-pext2 'chassis!=[[]]'

+check ovn-nbctl  --wait=sb clear logical_switch_port sw0-pext2 \
+ha_chassis_group -- set logical_switch_port sw0-pext2 'type=""'
  wait_row_count HA_Chassis_Group 0
+wait_row_count Port_Binding 0 logical_port=sw0-pext2 'chassis!=[[]]'
  check_row_count HA_Chassis 0
  
  as ovn-sb

@@ -2520,3 +2521,43 @@ check ovn-sbctl set chassis hv1 
other_config:port-up-notif=true
  wait_row_count nb:Logical_Switch_Port 1 up=false name=lsp1
  
  AT_CLEANUP

+
+AT_SETUP([ovn -- HA chassis group cleanup for external port ])
+ovn_start
+
+check ovn-nbctl ls-add sw0
+check ovn-nbctl lsp-add sw0 sw0-p1
+check ovn-nbctl lsp-set-type sw0-p1 external
+
+check ovn-sbctl chassis-add ch1 geneve 127.0.0.1
+check ovn-sbctl chassis-add ch2 geneve 127.0.0.2
+
+check ovn-nbctl ha-chassis-group-add hagrp1
+check ovn-nbctl ha-chassis-group-add-chassis hagrp1 ch1 20
+check ovn-nbctl --wait=sb ha-chassis-group-add-chassis hagrp1 ch2 10
+
+ha_grp1_uuid=$(fetch_column nb:ha_chassis_group _uuid)
+echo "ha grp1 uuid = $ha_grp1_uuid"
+ovn-nbctl list ha_chassis_group
+check ovn-nbctl set logical_switch_port sw0-p1 ha_chassis_group=$ha_grp1_uuid
+
+wait_row_count ha_chassis_group 1
+check ovn-nbctl clear logical_switch_port sw0-p1 ha_chassis_group
+wait_row_count ha_chassis_group 0
+
+check ovn-nbctl set logical_switch_port sw0-p1 ha_chassis_group=$ha_grp1_uuid
+wait_row_count ha_chassis_group 1
+sb_ha_grp1_uuid=$(fetch_column ha_chassis_group _uuid)
+
+echo
+echo "__file__:__line__:Check that port_binding sw0-p1 has ha_chassis_group 
set"
+
+check_column "$sb_ha_grp1_uuid" Port_Binding ha_chassis_group 
logical_port=sw0-p1
+
+AS_BOX([Clear ha_chassis_group for sw0-p1 and reset port type to normal port 
in the same txn])
+
+check ovn-nbctl clear logical_switch_port sw0-p1 ha_chassis_group -- set 
logical_switch_port sw0-p1 'type=""'
+wait_row_count ha_chassis_group 0
+check_column "" Port_Binding chassis logical_port=sw0-p1
+
+AT_CLEANUP



___
dev mailing list
d...@openvswitch.org
https://mail.openvswitch.org/mailman/listinfo/ovs-dev


Re: [ovs-dev] [PATCHv2] connmgr: Check nullptr inside ofmonitor_report()

2021-02-18 Thread William Tu
On Wed, Feb 17, 2021 at 1:09 PM Yifeng Sun  wrote:
>
> ovs-vswitchd could crash under these circumstances:
> 1. When one bridge is being destroyed, ofproto_destroy() is called and
> connmgr pointer of its ofproto struct is nullified. This ofproto struct is
> deallocated through 'ovsrcu_postpone(ofproto_destroy_defer__, p);'.
> 2. Before RCU enters quiesce state to actually free this ofproto struct,
> revalidator thread calls udpif_revalidator(), which could handle
> a learn flow and calls ofproto_flow_mod_learn(), it later calls
> ofmonitor_report() and ofproto struct's connmgr pointer is accessed.
>
> The crash stack trace is shown below:
>
> 0  ofmonitor_report (mgr=0x0, rule=rule@entry=0x7fa4ac067c30, 
> event=event@entry=NXFME_ADDED,
> reason=reason@entry=OFPRR_IDLE_TIMEOUT, abbrev_ofconn=0x0, abbrev_xid=0, 
> old_actions=old_actions@entry=0x0)
> at ofproto/connmgr.c:2160
> 1  0x7fa4d6803495 in add_flow_finish (ofproto=0x55d9075d4ab0, 
> ofm=, req=req@entry=0x0)
> at ofproto/ofproto.c:5221
> 2  0x7fa4d68036af in modify_flows_finish (req=0x0, ofm=0x7fa4980753f0, 
> ofproto=0x55d9075d4ab0)
> at ofproto/ofproto.c:5823
> 3  ofproto_flow_mod_finish (ofproto=0x55d9075d4ab0, 
> ofm=ofm@entry=0x7fa4980753f0, req=req@entry=0x0)
> at ofproto/ofproto.c:8088
> 4  0x7fa4d680372d in ofproto_flow_mod_learn_finish 
> (ofm=ofm@entry=0x7fa4980753f0,
> orig_ofproto=orig_ofproto@entry=0x0) at ofproto/ofproto.c:5439
> 5  0x7fa4d68072f9 in ofproto_flow_mod_learn (ofm=0x7fa4980753f0, 
> keep_ref=keep_ref@entry=true,
> limit=, below_limitp=below_limitp@entry=0x0) at 
> ofproto/ofproto.c:5499
> 6  0x7fa4d6835d33 in xlate_push_stats_entry (entry=0x7fa498012448, 
> stats=stats@entry=0x7fa4d2701a10,
> offloaded=offloaded@entry=false) at ofproto/ofproto-dpif-xlate-cache.c:127
> 7  0x7fa4d6835e3a in xlate_push_stats (xcache=, 
> stats=stats@entry=0x7fa4d2701a10,
> offloaded=offloaded@entry=false) at ofproto/ofproto-dpif-xlate-cache.c:181
> 8  0x7fa4d6822046 in revalidate_ukey (udpif=udpif@entry=0x55d90760b240, 
> ukey=ukey@entry=0x7fa4b0191660,
> stats=stats@entry=0x7fa4d2705118, 
> odp_actions=odp_actions@entry=0x7fa4d2701b50,
> reval_seq=reval_seq@entry=5655486242, 
> recircs=recircs@entry=0x7fa4d2701b40, offloaded=false)
> at ofproto/ofproto-dpif-upcall.c:2294
> 9  0x7fa4d6825aee in revalidate (revalidator=0x55d90769dd00) at 
> ofproto/ofproto-dpif-upcall.c:2683
> 10 0x7fa4d6825cf3 in udpif_revalidator (arg=0x55d90769dd00) at 
> ofproto/ofproto-dpif-upcall.c:936
> 11 0x7fa4d6259c9f in ovsthread_wrapper (aux_=) at 
> lib/ovs-thread.c:423
> 12 0x7fa4d582cea5 in start_thread () from /usr/lib64/libpthread.so.0
> 13 0x7fa4d504b96d in clone () from /usr/lib64/libc.so.6
>
> At the time of crash, the involved ofproto was already deallocated:
>
> (gdb) print *ofproto
> $1 = ..., name = 0x55d907602820 "nsx-managed", ..., ports = {...,
> one = 0x0, mask = 63, n = 0}, ..., connmgr = 0x0, ...
>
> This patch fixes it.
>
> VMware-BZ: #2700626
> Signed-off-by: Yifeng Sun 
> ---
> v1->v2: Add check for ofmonitor_flush, thanks William.
>

LGTM, thanks.
Acked-by: William Tu < u9012...@gmail.com>

CC Ilya and Ben to see if any comments.

I feel this kind of RCU issue is hard to find out, and
existing tools such as addressSanitizer are usually
not helpful.

William

>  ofproto/connmgr.c | 6 +-
>  1 file changed, 5 insertions(+), 1 deletion(-)
>
> diff --git a/ofproto/connmgr.c b/ofproto/connmgr.c
> index 9c5c633b4171..fa8f6cd0e83a 100644
> --- a/ofproto/connmgr.c
> +++ b/ofproto/connmgr.c
> @@ -2140,7 +2140,7 @@ ofmonitor_report(struct connmgr *mgr, struct rule *rule,
>   const struct rule_actions *old_actions)
>  OVS_REQUIRES(ofproto_mutex)
>  {
> -if (rule_is_hidden(rule)) {
> +if (!mgr || rule_is_hidden(rule)) {
>  return;
>  }
>
> @@ -2244,6 +2244,10 @@ ofmonitor_flush(struct connmgr *mgr)
>  {
>  struct ofconn *ofconn;
>
> +if (!mgr) {
> +return;
> +}
> +
>  LIST_FOR_EACH (ofconn, connmgr_node, >conns) {
>  struct rconn_packet_counter *counter = ofconn->monitor_counter;
>
> --
> 2.7.4
>
> ___
> dev mailing list
> d...@openvswitch.org
> https://mail.openvswitch.org/mailman/listinfo/ovs-dev
___
dev mailing list
d...@openvswitch.org
https://mail.openvswitch.org/mailman/listinfo/ovs-dev


Re: [ovs-dev] [PATCH ovn v10.1 0/6] Add DDlog implementation of ovn-northd

2021-02-18 Thread Ben Pfaff
This passed in the ovsrobot CI:
https://github.com/ovsrobot/ovn/actions/runs/579307688

I think that we have arrived at consensus to push this to ovn master
after branching happens tomorrow.  Please, let me know if I
misunderstood!
___
dev mailing list
d...@openvswitch.org
https://mail.openvswitch.org/mailman/listinfo/ovs-dev


[ovs-dev] [bug] uuid_from_string conflicts with FreeBSD libc

2021-02-18 Thread Dmitry Marakasov
Hi!

I've found an old bug in FreeBSD bugzilla:

https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=238331

reporting an incorrect behavior of ovs due to conflict of
uuid_from_string() defined in lib/uuid.* with the function with
same name from FreeBSD standard C library:

void uuid_from_string(const char*, uuid_t*, uint32_t*);

Here's FreeBSD manpage with the list of all functions (by pure
change tere are no other conflicts):

https://www.unix.com/man-page/FreeBSD/3/uuid_create/

The suggested workaround was to switch to static linking to make
ovs' symbol used.

IMO this should be fixed upstream, probably by prefixing uuid_*
functions to avoid this and similar conflicts.

-- 
Dmitry Marakasov   .   55B5 0596 FF1E 8D84 5F56  9510 D35A 80DD F9D2 F77D
amd...@amdmi3.ru  ..:  https://github.com/AMDmi3

___
dev mailing list
d...@openvswitch.org
https://mail.openvswitch.org/mailman/listinfo/ovs-dev


Re: [ovs-dev] [OVN Patch v14 1/3] ovn-libs: Add support for parallel processing

2021-02-18 Thread Mark Michelson

Hi Anton, in short:

Acked-by: Mark Michelson 

I think this can go in as-is. My only question is with regards to how 
dp_groups are handled. The current patch makes it so that when dp_groups 
are used, we parallelize the work. However, instead of each thread 
creating discrete segments of lflows, each thread shares a reference to 
the same large lflow hmap. This means the threads have to lock the 
pertinent hash row each time they add a lflow to the hmap. This makes 
sense since the entire lflow hmap needs to be taken into account when 
determining if a flow is repeated between different datapaths.


I'm curious if this contention might result in poorer parallization 
speedup. Without having done any profiling, my assumption is that this 
shouldn't perform worse than single-threaded code, but that it likely 
isn't performing that much better either. Because this isn't actively 
*harming* performance, that's why I went ahead and acked the patch series.


Once we have run some performance tests, it would be worth determining 
if the algorithm used for dp_groups could be improved. I have a couple 
of thoughts:


1) It might just make sense to disable parallelization when dp_groups 
are enabled. This certainly wouldn't help performance, but it would 
simplify northd somewhat. This might be an OK tradeoff if the 
performance improvement from parallelization with dp_groups is 
insignificant.


2) We could fully parallelize lflow table creation just like we do when 
dp_groups are disabled: split the lflow hmap into segments for each 
worker to fill in, and then merge them together once all threads are 
complete. Then after merging, we could iterate over the completed lflow 
hmap and determine the dp_groups at that point, rather than when 
inserting the lflow into the hmap. This extra hmap traversal might slow 
things down some, but uncontended parallelization could more than offset 
that cost.


What do you think about these ideas? I bring them up because OVN is 
trending towards eventually having dp_groups enabled and no longer being 
disable-able.


On 2/12/21 9:49 AM, Anton Ivanov wrote:

This adds a set of functions and macros intended to process
hashes in parallel.

The principles of operation are documented in the fasthmap.h

If these one day go into the OVS tree, the OVS tree versions
would be used in preference.

Signed-off-by: Anton Ivanov 
---
  lib/automake.mk |   2 +
  lib/ovn-parallel-hmap.c | 455 
  lib/ovn-parallel-hmap.h | 285 +
  3 files changed, 742 insertions(+)
  create mode 100644 lib/ovn-parallel-hmap.c
  create mode 100644 lib/ovn-parallel-hmap.h

diff --git a/lib/automake.mk b/lib/automake.mk
index 250c7aefa..781be2109 100644
--- a/lib/automake.mk
+++ b/lib/automake.mk
@@ -13,6 +13,8 @@ lib_libovn_la_SOURCES = \
lib/expr.c \
lib/extend-table.h \
lib/extend-table.c \
+   lib/ovn-parallel-hmap.h \
+   lib/ovn-parallel-hmap.c \
lib/ip-mcast-index.c \
lib/ip-mcast-index.h \
lib/mcast-group-index.c \
diff --git a/lib/ovn-parallel-hmap.c b/lib/ovn-parallel-hmap.c
new file mode 100644
index 0..06aa95aba
--- /dev/null
+++ b/lib/ovn-parallel-hmap.c
@@ -0,0 +1,455 @@
+/*
+ * Copyright (c) 2020 Red Hat, Inc.
+ * Copyright (c) 2008, 2009, 2010, 2012, 2013, 2015, 2019 Nicira, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include "fatal-signal.h"
+#include "util.h"
+#include "openvswitch/vlog.h"
+#include "openvswitch/hmap.h"
+#include "openvswitch/thread.h"
+#include "ovn-parallel-hmap.h"
+#include "ovs-atomic.h"
+#include "ovs-thread.h"
+#include "ovs-numa.h"
+#include "random.h"
+
+VLOG_DEFINE_THIS_MODULE(ovn_parallel_hmap);
+
+#ifndef OVS_HAS_PARALLEL_HMAP
+
+#define WORKER_SEM_NAME "%x-%p-%x"
+#define MAIN_SEM_NAME "%x-%p-main"
+
+/* These are accessed under mutex inside add_worker_pool().
+ * They do not need to be atomic.
+ */
+
+static atomic_bool initial_pool_setup = ATOMIC_VAR_INIT(false);
+static bool can_parallelize = false;
+
+/* This is set only in the process of exit and the set is
+ * accompanied by a fence. It does not need to be atomic or be
+ * accessed under a lock.
+ */
+
+static bool workers_must_exit = false;
+
+static struct ovs_list worker_pools = OVS_LIST_INITIALIZER(_pools);
+
+static struct ovs_mutex init_mutex = 

Re: [ovs-dev] [PATCH ovn v10.1 6/6] ovn-northd-ddlog: New implementation of ovn-northd based on ddlog.

2021-02-18 Thread 0-day Robot
Bleep bloop.  Greetings Ben Pfaff, I am a robot and I have tried out your patch.
Thanks for your contribution.

I encountered some error that I wasn't expecting.  See the details below.


checkpatch:
WARNING: Comment with 'xxx' marker
#3724 FILE: northd/ovn-northd-ddlog.c:166:
.cs = ovsdb_cs_create(database, 1 /* XXX */, _cs_ops, ctx),

WARNING: Comment with 'xxx' marker
#4512 FILE: northd/ovn-northd-ddlog.c:954:
 * XXX If the transaction we're sending to the database fails, then

WARNING: Line lacks whitespace around operator
WARNING: Line lacks whitespace around operator
WARNING: Line lacks whitespace around operator
#4565 FILE: northd/ovn-northd-ddlog.c:1007:
  --ovnnb-db=DATABASE   connect to ovn-nb database at DATABASE\n\

WARNING: Line lacks whitespace around operator
WARNING: Line lacks whitespace around operator
WARNING: Line lacks whitespace around operator
#4567 FILE: northd/ovn-northd-ddlog.c:1009:
  --ovnsb-db=DATABASE   connect to ovn-sb database at DATABASE\n\

WARNING: Line lacks whitespace around operator
WARNING: Line lacks whitespace around operator
#4569 FILE: northd/ovn-northd-ddlog.c:1011:
  --unixctl=SOCKET  override default control socket name\n\

WARNING: Line has trailing whitespace
#6344 FILE: northd/ovn_northd.dl:176:
var l3dgw_port = peer.and_then(|p| p.router.l3dgw_port),

WARNING: Line has non-spaces leading whitespace
WARNING: Line has trailing whitespace
#9126 FILE: northd/ovn_northd.dl:2958:
 

WARNING: Line has non-spaces leading whitespace
WARNING: Line has trailing whitespace
#12818 FILE: northd/ovn_northd.dl:6650:


WARNING: Line has non-spaces leading whitespace
WARNING: Line has trailing whitespace
#13787 FILE: northd/ovn_northd.dl:7619:


WARNING: Line has trailing whitespace
#13988 FILE: northd/ovn_northd.dl:7820:
}

WARNING: Line has non-spaces leading whitespace
WARNING: Line has trailing whitespace
#13989 FILE: northd/ovn_northd.dl:7821:
  

WARNING: Line has non-spaces leading whitespace
WARNING: Line has trailing whitespace
#13990 FILE: northd/ovn_northd.dl:7822:
 

Lines checked: 14607, Warnings: 22, Errors: 0


Please check this out.  If you feel there has been an error, please email 
acon...@redhat.com

Thanks,
0-day Robot
___
dev mailing list
d...@openvswitch.org
https://mail.openvswitch.org/mailman/listinfo/ovs-dev


Re: [ovs-dev] [PATCH ovn v10.1 1/6] Export `VLOG_WARN` and `VLOG_ERR` from libovn for use in ddlog

2021-02-18 Thread 0-day Robot
Bleep bloop.  Greetings Ben Pfaff, I am a robot and I have tried out your patch.
Thanks for your contribution.

I encountered some error that I wasn't expecting.  See the details below.


checkpatch:
WARNING: Unexpected sign-offs from developers who are not authors or co-authors 
or committers: Ben Pfaff 
Lines checked: 77, Warnings: 1, Errors: 0


Please check this out.  If you feel there has been an error, please email 
acon...@redhat.com

Thanks,
0-day Robot
___
dev mailing list
d...@openvswitch.org
https://mail.openvswitch.org/mailman/listinfo/ovs-dev


[ovs-dev] [PATCH ovn v10.1 2/6] tests: Prepare for multiple northd types.

2021-02-18 Thread Ben Pfaff
The idea is to run each test twice, once with ovn-northd, once
with ovn-northd-ddlog.  To do that, we add a macro OVN_FOR_EACH_NORTHD
and bracket each test that uses ovn-northd in it.

Signed-off-by: Ben Pfaff 
Acked-by: Dumitru Ceara 
---
 tests/ovn-ic.at |  11 +-
 tests/ovn-macros.at |  96 +--
 tests/ovn-northd.at | 100 ---
 tests/ovn.at| 288 
 tests/ovs-macros.at |  20 +--
 tests/system-ovn.at | 124 ++-
 6 files changed, 528 insertions(+), 111 deletions(-)

diff --git a/tests/ovn-ic.at b/tests/ovn-ic.at
index 0638af401295..2a4fba031f36 100644
--- a/tests/ovn-ic.at
+++ b/tests/ovn-ic.at
@@ -1,4 +1,5 @@
 AT_BANNER([OVN Interconnection Controller])
+OVN_FOR_EACH_NORTHD([
 AT_SETUP([ovn-ic -- AZ register])
 
 ovn_init_ic_db
@@ -29,7 +30,9 @@ availability-zone az3
 OVN_CLEANUP_IC([az1], [az2])
 
 AT_CLEANUP
+])
 
+OVN_FOR_EACH_NORTHD([
 AT_SETUP([ovn-ic -- transit switch handling])
 
 ovn_init_ic_db
@@ -59,7 +62,9 @@ check_column ts2 nb:Logical_Switch name
 OVN_CLEANUP_IC([az1])
 
 AT_CLEANUP
+])
 
+OVN_FOR_EACH_NORTHD([
 AT_SETUP([ovn-ic -- gateway sync])
 
 ovn_init_ic_db
@@ -120,8 +125,9 @@ OVN_CLEANUP_SBOX(gw2)
 OVN_CLEANUP_IC([az1], [az2])
 
 AT_CLEANUP
+])
 
-
+OVN_FOR_EACH_NORTHD([
 AT_SETUP([ovn-ic -- port sync])
 
 ovn_init_ic_db
@@ -185,7 +191,9 @@ OVN_CLEANUP_SBOX(gw1)
 OVN_CLEANUP_IC([az1], [az2])
 
 AT_CLEANUP
+])
 
+OVN_FOR_EACH_NORTHD([
 AT_SETUP([ovn-ic -- route sync])
 
 ovn_init_ic_db
@@ -310,3 +318,4 @@ OVS_WAIT_WHILE([ovn_as az1 ovn-nbctl lr-route-list lr1 | 
grep learned | grep 10.
 OVN_CLEANUP_IC([az1], [az2])
 
 AT_CLEANUP
+])
diff --git a/tests/ovn-macros.at b/tests/ovn-macros.at
index 2ba29a960edc..a6b908741673 100644
--- a/tests/ovn-macros.at
+++ b/tests/ovn-macros.at
@@ -47,10 +47,12 @@ m4_define([OVN_CLEANUP],[
 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
 
 as northd
-OVS_APP_EXIT_AND_WAIT([ovn-northd])
+OVS_APP_EXIT_AND_WAIT([[$NORTHD_TYPE]])
 
-as northd-backup
-OVS_APP_EXIT_AND_WAIT([ovn-northd])
+if test -d northd-backup; then
+as northd-backup
+OVS_APP_EXIT_AND_WAIT([[$NORTHD_TYPE]])
+fi
 
 OVN_CLEANUP_VSWITCH([main])
 ])
@@ -69,10 +71,12 @@ m4_define([OVN_CLEANUP_AZ],[
 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
 
 as $1/northd
-OVS_APP_EXIT_AND_WAIT([ovn-northd])
+OVS_APP_EXIT_AND_WAIT([[$NORTHD_TYPE]])
 
-as $1/northd-backup
-OVS_APP_EXIT_AND_WAIT([ovn-northd])
+if test -d $1/northd-backup; then
+as $1/northd-backup
+OVS_APP_EXIT_AND_WAIT([[$NORTHD_TYPE]])
+fi
 
 as $1/ic
 OVS_APP_EXIT_AND_WAIT([ovn-ic])
@@ -134,15 +138,48 @@ ovn_init_ic_db () {
 ovn_init_db ovn-ic-sb
 }
 
-# ovn_start [AZ]
+# ovn_start_northd (primary|backup) [AZ]
+ovn_start_northd() {
+local priority=$1
+local AZ=$2
+local msg_prefix=${AZ:+$AZ: }
+local d_prefix=${AZ:+$AZ/}
+
+local suffix=
+case $priority in
+backup) suffix=-backup ;;
+esac
+
+local northd_args=
+case ${NORTHD_TYPE:=ovn-northd} in
+ovn-northd) ;;
+ovn-northd-ddlog) 
northd_args="--ddlog-record=${AZ:+$AZ/}replay$suffix.dat -v" ;;
+esac
+
+local name=${d_prefix}northd${suffix}
+echo "${prefix}starting $name"
+test -d "$ovs_base/$name" || mkdir "$ovs_base/$name"
+as $name start_daemon $NORTHD_TYPE $northd_args -vjsonrpc \
+   --ovnnb-db=$OVN_NB_DB --ovnsb-db=$OVN_SB_DB
+}
+
+# ovn_start [--no-backup-northd] [AZ]
 #
 # Creates and initializes ovn-sb and ovn-nb databases and starts their
 # ovsdb-server instance, sets appropriate environment variables so that
 # ovn-sbctl and ovn-nbctl use them by default, and starts ovn-northd running
 # against them.
 ovn_start () {
-if test -n "$1"; then
-mkdir "$ovs_base"/$1
+local backup_northd=:
+case $1 in
+--no-backup-northd) backup_northd=false; shift ;;
+esac
+local AZ=$1
+local msg_prefix=${AZ:+$AZ: }
+local d_prefix=${AZ:+$AZ/}
+
+if test -n "$AZ"; then
+mkdir "$ovs_base"/$AZ
 fi
 
 ovn_init_db ovn-sb $1; ovn-sbctl init
@@ -150,36 +187,19 @@ ovn_start () {
 if test -n "$1"; then
 ovn-nbctl set NB_Global . name=$1
 fi
-local ovn_sb_db=$OVN_SB_DB
-local ovn_nb_db=$OVN_NB_DB
 
-local as_d=northd
-if test -n "$1"; then
-as_d=$1/$as_d
+ovn_start_northd primary $AZ
+if $backup_northd; then
+ovn_start_northd backup $AZ
 fi
-echo "starting ovn-northd"
-mkdir "$ovs_base"/$as_d
-as $as_d start_daemon ovn-northd -v \
-   --ovnnb-db=$ovn_nb_db \
-   --ovnsb-db=$ovn_sb_db
 
-as_d=northd-backup
-if test -n "$1"; then
-as_d=$1/$as_d
-fi
-echo "starting backup ovn-northd"
-mkdir "$ovs_base"/$as_d
-as $as_d start_daemon ovn-northd -v \
-   --ovnnb-db=$ovn_nb_db \
-   --ovnsb-db=$ovn_sb_db
+if test -n "$AZ"; then

[ovs-dev] [PATCH ovn v10.1 4/6] ovn-northd: Simplify logic in build_bfd_table().

2021-02-18 Thread Ben Pfaff
The code here checked whether 'bfd_e' was null even though that wasn't
necessary given the control flow just above it.

Signed-off-by: Ben Pfaff 
---
 northd/ovn-northd.c | 16 
 1 file changed, 8 insertions(+), 8 deletions(-)

diff --git a/northd/ovn-northd.c b/northd/ovn-northd.c
index 39d798782002..8c74c9fd66b9 100644
--- a/northd/ovn-northd.c
+++ b/northd/ovn-northd.c
@@ -7457,15 +7457,15 @@ build_bfd_table(struct northd_context *ctx, struct hmap 
*bfd_connections,
 int d_mult = nb_bt->n_detect_mult ? nb_bt->detect_mult[0]
   : BFD_DEF_DETECT_MULT;
 sbrec_bfd_set_detect_mult(sb_bt, d_mult);
-} else if (strcmp(bfd_e->sb_bt->status, nb_bt->status)) {
-if (!strcmp(nb_bt->status, "admin_down") ||
-!strcmp(bfd_e->sb_bt->status, "admin_down")) {
-sbrec_bfd_set_status(bfd_e->sb_bt, nb_bt->status);
-} else {
-nbrec_bfd_set_status(nb_bt, bfd_e->sb_bt->status);
+} else {
+if (strcmp(bfd_e->sb_bt->status, nb_bt->status)) {
+if (!strcmp(nb_bt->status, "admin_down") ||
+!strcmp(bfd_e->sb_bt->status, "admin_down")) {
+sbrec_bfd_set_status(bfd_e->sb_bt, nb_bt->status);
+} else {
+nbrec_bfd_set_status(nb_bt, bfd_e->sb_bt->status);
+}
 }
-}
-if (bfd_e) {
 build_bfd_update_sb_conf(nb_bt, bfd_e->sb_bt);
 
 hmap_remove(_only, _e->hmap_node);
-- 
2.28.0

___
dev mailing list
d...@openvswitch.org
https://mail.openvswitch.org/mailman/listinfo/ovs-dev


[ovs-dev] [PATCH ovn v10.1 5/6] ovn-sb: Allow Multicast_Group to have empty set of ports.

2021-02-18 Thread Ben Pfaff
I don't know a good reason to intentionally create an empty multicast
group, but disallowing empty multicast groups has an odd side effect:
you can delete all but one of the ports that a group contains and the
database will happily remove the ports from the group automatically
(because 'ports' is a set of weak references) but if you try to delete
the last port that the group contained, the database server will reject
the whole transaction.  That's really weird.  By allowing a multicast
group with no ports, we avoid this special case.

Signed-off-by: Ben Pfaff 
---
 ovn-sb.ovsschema | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/ovn-sb.ovsschema b/ovn-sb.ovsschema
index 0d20f0826646..07eb54b10dd4 100644
--- a/ovn-sb.ovsschema
+++ b/ovn-sb.ovsschema
@@ -1,7 +1,7 @@
 {
 "name": "OVN_Southbound",
-"version": "20.15.0",
-"cksum": "539683023 25965",
+"version": "20.16.0",
+"cksum": "3127541865 25965",
 "tables": {
 "SB_Global": {
 "columns": {
@@ -133,7 +133,7 @@
 "ports": {"type": {"key": {"type": "uuid",
"refTable": "Port_Binding",
"refType": "weak"},
-   "min": 1, "max": "unlimited"}}},
+   "min": 0, "max": "unlimited"}}},
 "indexes": [["datapath", "tunnel_key"],
 ["datapath", "name"]],
 "isRoot": true},
-- 
2.28.0

___
dev mailing list
d...@openvswitch.org
https://mail.openvswitch.org/mailman/listinfo/ovs-dev


[ovs-dev] [PATCH ovn v10.1 3/6] tests: Wait for updates in "check BFD config propagation to BFD" test.

2021-02-18 Thread Ben Pfaff
Otherwise this test is racy because it assumes that northd finishes
its updates between the ovn-nbctl changes and the subsequent checks.

Also, simplify some series of "check_column" into single
"check_row_count" calls (that then become "wait_row_count").

Signed-off-by: Ben Pfaff 
---
 tests/ovn-northd.at | 44 ++--
 1 file changed, 14 insertions(+), 30 deletions(-)

diff --git a/tests/ovn-northd.at b/tests/ovn-northd.at
index e4fceff037a8..1a941efe9b5c 100644
--- a/tests/ovn-northd.at
+++ b/tests/ovn-northd.at
@@ -2463,55 +2463,39 @@ ovn-nbctl create bfd logical_port=r0-sw2 
dst_ip=192.168.20.2 status=down min_tx=
 ovn-nbctl create bfd logical_port=r0-sw3 dst_ip=192.168.30.2 status=down
 ovn-nbctl create bfd logical_port=r0-sw4 dst_ip=192.168.40.2 status=down 
min_tx=0 detect_mult=0
 
-check_column 10 bfd detect_mult logical_port=r0-sw1
-check_column "192.168.10.2" bfd dst_ip logical_port=r0-sw1
-check_column 250 bfd min_rx logical_port=r0-sw1
-check_column 250 bfd min_tx logical_port=r0-sw1
-check_column admin_down bfd status logical_port=r0-sw1
-
-check_column 20 bfd detect_mult logical_port=r0-sw2
-check_column "192.168.20.2" bfd dst_ip logical_port=r0-sw2
-check_column 500 bfd min_rx logical_port=r0-sw2
-check_column 500 bfd min_tx logical_port=r0-sw2
-check_column admin_down bfd status logical_port=r0-sw2
-
-check_column 5 bfd detect_mult logical_port=r0-sw3
-check_column "192.168.30.2" bfd dst_ip logical_port=r0-sw3
-check_column 1000 bfd min_rx logical_port=r0-sw3
-check_column 1000 bfd min_tx logical_port=r0-sw3
-check_column admin_down bfd status logical_port=r0-sw3
+wait_row_count bfd 1 logical_port=r0-sw1 detect_mult=10 dst_ip=192.168.10.2 \
+ min_rx=250 min_tx=250 status=admin_down
+wait_row_count bfd 1 logical_port=r0-sw2 detect_mult=20 dst_ip=192.168.20.2 \
+ min_rx=500 min_tx=500 status=admin_down
+wait_row_count bfd 1 logical_port=r0-sw3 detect_mult=5 dst_ip=192.168.30.2 \
+ min_rx=1000 min_tx=1000 status=admin_down
 
 uuid=$(fetch_column nb:bfd _uuid logical_port=r0-sw1)
-check ovn-nbctl set bfd $uuid min_tx=1000
-check ovn-nbctl set bfd $uuid min_rx=1000
-check ovn-nbctl set bfd $uuid detect_mult=100
+check ovn-nbctl set bfd $uuid min_tx=1000 min_rx=1000 detect_mult=100
 
 uuid_2=$(fetch_column nb:bfd _uuid logical_port=r0-sw2)
 check ovn-nbctl clear bfd $uuid_2 min_rx
-check_column 1000 bfd min_rx logical_port=r0-sw2
-
-check_column 1000 bfd min_tx logical_port=r0-sw1
-check_column 1000 bfd min_rx logical_port=r0-sw1
-check_column 100 bfd detect_mult logical_port=r0-sw1
+wait_row_count bfd 1 logical_port=r0-sw2 min_rx=1000
+wait_row_count bfd 1 logical_port=r0-sw1 min_rx=1000 min_tx=1000 
detect_mult=100
 
 check ovn-nbctl --bfd=$uuid lr-route-add r0 100.0.0.0/8 192.168.10.2
-check_column down bfd status logical_port=r0-sw1
+wait_column down bfd status logical_port=r0-sw1
 AT_CHECK([ovn-nbctl lr-route-list r0 | grep 192.168.10.2 | grep -q bfd],[0])
 
 check ovn-nbctl --bfd lr-route-add r0 200.0.0.0/8 192.168.20.2
-check_column down bfd status logical_port=r0-sw2
+wait_column down bfd status logical_port=r0-sw2
 AT_CHECK([ovn-nbctl lr-route-list r0 | grep 192.168.20.2 | grep -q bfd],[0])
 
 check ovn-nbctl --bfd lr-route-add r0 240.0.0.0/8 192.168.50.2 r0-sw5
-check_column down bfd status logical_port=r0-sw5
+wait_column down bfd status logical_port=r0-sw5
 AT_CHECK([ovn-nbctl lr-route-list r0 | grep 192.168.50.2 | grep -q bfd],[0])
 
 route_uuid=$(fetch_column nb:logical_router_static_route _uuid 
ip_prefix="100.0.0.0/8")
 check ovn-nbctl clear logical_router_static_route $route_uuid bfd
-check_column admin_down bfd status logical_port=r0-sw1
+wait_column admin_down bfd status logical_port=r0-sw1
 
 ovn-nbctl destroy bfd $uuid
-check_row_count bfd 3
+wait_row_count bfd 3
 
 AT_CLEANUP
 ])
-- 
2.28.0

___
dev mailing list
d...@openvswitch.org
https://mail.openvswitch.org/mailman/listinfo/ovs-dev


[ovs-dev] [PATCH ovn v10.1 1/6] Export `VLOG_WARN` and `VLOG_ERR` from libovn for use in ddlog

2021-02-18 Thread Ben Pfaff
From: Leonid Ryzhyk 

Export `ddlog_warn` and `ddlog_err` functions that are just wrappers
around `VLOG_WARN` and `VLOG_ERR`.  This is not ideal because the
functions are exported by `ovn_util.c` and the resulting log messages use
`ovn_util` as module name.  More importantly, these functions do not do
log rate limiting.

Signed-off-by: Leonid Ryzhyk 
Signed-off-by: Ben Pfaff 
Acked-by: Dumitru Ceara 
---
 TODO.rst   |  6 ++
 lib/ovn-util.c | 15 +++
 lib/ovn-util.h |  5 +
 3 files changed, 26 insertions(+)

diff --git a/TODO.rst b/TODO.rst
index c15815539f4f..ecfe62870fb0 100644
--- a/TODO.rst
+++ b/TODO.rst
@@ -153,6 +153,12 @@ OVN To-do List
   hashtable lookup in parse_port_group() which can be avoided when we are sure
   that the Southbound DB uses the new format.
 
+* ovn-northd-ddlog: Calls to warn() and err() from DDlog code would be
+  better refactored to use the Warning[] relation (and introduce an
+  Error[] relation once we want to issue some errors that way).  This
+  would be easier with some improvements in DDlog to more easily
+  output to multiple relations from a single production.
+
 * IP Multicast Relay
 
   * When connecting bridged logical switches (localnet) to logical routers
diff --git a/lib/ovn-util.c b/lib/ovn-util.c
index b6471063ef7e..a5e0ecd214b2 100644
--- a/lib/ovn-util.c
+++ b/lib/ovn-util.c
@@ -758,3 +758,18 @@ ovn_get_internal_version(void)
  sbrec_get_db_version(),
  N_OVNACTS, OVN_INTERNAL_MINOR_VER);
 }
+
+#ifdef DDLOG
+/* Callbacks used by the ddlog northd code to print warnings and errors. */
+void
+ddlog_warn(const char *msg)
+{
+VLOG_WARN("%s", msg);
+}
+
+void
+ddlog_err(const char *msg)
+{
+VLOG_ERR("%s", msg);
+}
+#endif
diff --git a/lib/ovn-util.h b/lib/ovn-util.h
index 08234611838a..55c7bf382a95 100644
--- a/lib/ovn-util.h
+++ b/lib/ovn-util.h
@@ -261,4 +261,9 @@ BUILD_ASSERT_DECL(SCTP_INIT_CHUNK_LEN == sizeof(struct 
sctp_init_chunk));
 /* See RFC 4960 Sections 3.3.7 and 8.5.1 for information on this flag. */
 #define SCTP_ABORT_CHUNK_FLAG_T (1 << 0)
 
+#ifdef DDLOG
+void ddlog_warn(const char *msg);
+void ddlog_err(const char *msg);
+#endif
+
 #endif
-- 
2.28.0

___
dev mailing list
d...@openvswitch.org
https://mail.openvswitch.org/mailman/listinfo/ovs-dev


[ovs-dev] [PATCH ovn v10.1 0/6] Add DDlog implementation of ovn-northd

2021-02-18 Thread Ben Pfaff
v10.1:
  - Fold in fix to northd makefile.

v10:
  - Fix linking problem reported by Dumitru and others.
  - Update to ddlog 0.36.0 (thanks Leonid!).
  - Port OVN commits up to 858d1dd716db ("ofctrl: Fix the assert seen when 
flood removing flows.")
  - Fix IGMP and MLD snoop/querier/reply tests (thanks Dumitru!).
  - New commit "ovn-sb: Allow Multicast_Group to have empty set of ports."
  - New commit "ovn-northd: Simplify logic in build_bfd_table()."
  - New commit "tests: Wait for updates in "check BFD config propagation to 
BFD" test."

v9:
  - Add ddlog.stamp to BUILT_SOURCES, to fix the dependencies "for sure".
  - Rebase against ovn/master.
  - Port commit fdf295d5eb3a ("pinctrl: Honor
always_learn_from_arp_request for self created MAC_Bindings.")
  - Update to work with and require v2 of the ovsdb-cs library (see
https://mail.openvswitch.org/pipermail/ovs-dev/2020-December/378180.html).
  - All non-skipped tests pass, although some are still racy.
  - This is also available as the ddlog14 branch here:
https://github.com/blp/ovs-reviews/commits/ddlog14
  - Haven't done performance tests.  I aim to do that for v10.

v8:
  - Rebase against latest ovn master.
  - Port commit f9cab11d5fab ("Allow explicit setting of the SNAT zone
on a gateway router.")
  - Port commit f1119c125765 ("northd: Refactor load balancer vip parsing.")
  - Port commit 1dd27ea7aea4 ("Provide the option to pin
ovn-controller and ovn-northd to a specific version.").
  - Port commit 880dca99eaf7 ("northd: Enhance the implementation of
ACL log meters (pre-ddlog merge).")
  - Make ovn-northd-ddlog use the new ovsdb-cs (client sync) library
proposed for OVS
(https://mail.openvswitch.org/pipermail/ovs-dev/2020-November/377828.html).
In addition to eliminating duplicated code, this should make it
able to connect to a raft cluster.
  - Further improvements to test improvement patch (mostly added "check"s
and AS_BOX(...) to announce parts of a test)
  - Modernize some of the ddlog code a bit, e.g. by using the method-like
calls such as foo.get("key") in place of map_get(foo, "key").

v7:
  - Fixed "make dist" (thanks to Numan for reporting this.)
  - Fix probe interval setting (thanks to Numan again).
  - Small amount of improvement of OVN DDlog code (use lambdas in more places).
  - Fine-tuning of ovn-northd-ddlog code for jsonrpc session usage.
  - Fix newline issues in tests reported by Dumitru.
  - Add ack from Dumitru.

v6:
  - Applied and dropped patch for "test a == b".
  - Applied and dropped patch to allow more args to wait_for_row_count().
  - Applied and dropped ARP/ND broadcast test improvement patch.
  - Fix whitespace in patch to export ddlog_warn() and ddlog_err().

v5:
  - Drop patch for ACL log meters (this was included in v4.1 by mistake).
  - In addition to waiting for database, also wait for ports to come up.
  - New patch to support more arguments to wait_for_row_count that waiting
for ports indirectly needed.
  - Port commit c29221d9322a ("Allow VLAN traffic when LS:vlan-passthru=true").
  - Port commit 36a8745de859 ("Add support for DHCP options 28 (Broadcast 
Address)")
  - Add patch to improve "ARP/ND request broadcast limiting" test.

v4:
  - Fix dependencies for parallel build.
  - Fix spelling error in documentation.
  - Use --wait=sb, not --wait=hv, when no chassis are running.
  - Fixed IGMP and MLD tests by porting commit 9d2e8d32fb98
("ofctrl.c: Fix duplicated flow handling in I-P while merging
opposite changes."), which I had missed before.

Ben Pfaff (4):
  tests: Prepare for multiple northd types.
  tests: Wait for updates in "check BFD config propagation to BFD" test.
  ovn-northd: Simplify logic in build_bfd_table().
  ovn-sb: Allow Multicast_Group to have empty set of ports.

Leonid Ryzhyk (2):
  Export `VLOG_WARN` and `VLOG_ERR` from libovn for use in ddlog
  ovn-northd-ddlog: New implementation of ovn-northd based on ddlog.

 Documentation/automake.mk |2 +
 Documentation/intro/install/general.rst   |   31 +-
 Documentation/topics/debugging-ddlog.rst  |  280 +
 Documentation/topics/index.rst|1 +
 Documentation/tutorials/ddlog-new-feature.rst |  362 +
 Documentation/tutorials/index.rst |1 +
 NEWS  |6 +
 TODO.rst  |6 +
 acinclude.m4  |   43 +
 build-aux/automake.mk |1 +
 build-aux/libtool-deps|   35 +
 configure.ac  |5 +
 lib/ovn-util.c|   15 +
 lib/ovn-util.h|5 +
 m4/ovn.m4 |   16 +
 northd/.gitignore |4 +
 northd/automake.mk|  108 +
 northd/helpers.dl |   96 +
 northd/ipam.dl   

Re: [ovs-dev] [PATCH ovn v3] northd: Provide the Gateway router option 'lb_force_snat_ip' to take router port ips.

2021-02-18 Thread Mark Gray
On 18/02/2021 19:00, num...@ovn.org wrote:
> From: Numan Siddique 
> 
> When a Gateway router is configured with a load balancer
> and it is also configured with options:lb_force_snat_ip=,
> OVN after load balancing the destination IP to one of the
> backend also does a NAT on the source ip with the
> lb_force_snat_ip if the packet is destined to a load balancer
> VIP.
> 
> There is a problem with the snat of source ip to 'lb_force_snat_ip'
> in one particular usecase.  When the packet enters the Gateway router
> from a provider logical switch destined to the load balancer VIP,
> then it is first load balanced to one of the backend and then
> the source ip is snatted to 'lb_force_snat_ip'.  If the chosen
> backend is reachable via the provider logical switch, then the
> packet is hairpinned back and it may hit the wire with
> the source ip 'lb_force_snat_ip'.  If 'lb_force_snat_ip' happens
> to be an OVN internal IP then the packet may be dropped.
> 
> This patch addresses this issue by providing the option to
> set the option - 'lb_force_snat_ip=router_ip'.  If 'router_ip'
> is set, then OVN will snat the load balanced packet to the
> router ip of the logical router port which is chosen as 'outport'
> in lr_in_ip_routing stage.
> 
> Example.
> 
> If the gateway router is
> 
> ovn-nbctl show lr0
> router 68f20092-5563-44b8-9ccb-b11de3e3a66c (lr0)
> port lr0-sw0
> mac: "00:00:00:00:ff:01"
> networks: ["10.0.0.1/24"]
> port lr0-public
> mac: "00:00:20:20:12:13"
> networks: ["172.168.0.100/24"]
> 
> Then the below logical flows are added if 'lb_force_snat_ip'
> is configured to 'router_ip'.
> 
> table=1 (lr_out_snat), priority=110
>match=(flags.force_snat_for_lb == 1 && ip4 && outport == "lr0-public"),
>action=(ct_snat(172.168.0.100);)
> 
> table=1 (lr_out_snat), priority=110
>match=(flags.force_snat_for_lb == 1 && ip4 && outport == "lr0-sw0")
>action=(ct_snat(10.0.0.1);)
> 
> For the above described scenario, the packet will have source ip as
> 172.168.0.100 which belongs to the provider logical switch CIDR.
> 
> Reported-by: Tim Rozet 
> Signed-off-by: Numan Siddique 
> ---
>  northd/ovn-northd.8.xml | 35 
>  northd/ovn-northd.c | 91 +
>  ovn-nb.xml  | 33 ++-
>  tests/ovn-northd.at | 79 +++
>  4 files changed, 220 insertions(+), 18 deletions(-)
> 
> diff --git a/northd/ovn-northd.8.xml b/northd/ovn-northd.8.xml
> index 2f8b4e8c30..1d8f5edee1 100644
> --- a/northd/ovn-northd.8.xml
> +++ b/northd/ovn-northd.8.xml
> @@ -3654,6 +3654,32 @@ nd_ns {
>flags.force_snat_for_dnat == 1  ip with an
>action ct_snat(B);.
>  
> +  
> +
> +  
> +
> +  If the Gateway router in the OVN Northbound database has been
> +  configured to force SNAT a packet (that has been previously
> +  load-balanced) using router IP (i.e  +  table="Logical_Router"/>:lb_force_snat_ip=router_ip), then for
> +  each logical router port P attached to the Gateway
> +  router, a priority-110 flow matches
> +  flags.force_snat_for_lb == 1  outport == 
> P
> +   with an action ct_snat(R);
> +  where R is the IP configured on the router port.
> +  If R is an IPv4 address then the match will also
> +  include ip4 and if it is an IPv6 address, then the
> +  match will also include ip6.
> +
> +
> +
> +  If the logical router port P is configured with multiple
> +  IPv4 and multiple IPv6 addresses, only the first IPv4 and first 
> IPv6
> +  address is considered.
> +
> +  
> +
> +  
>  
>If the Gateway router in the OVN Northbound database has been
>configured to force SNAT a packet (that has been previously
> @@ -3661,6 +3687,9 @@ nd_ns {
>flags.force_snat_for_lb == 1  ip with an
>action ct_snat(B);.
>  
> +  
> +
> +  
>  
>For each configuration in the OVN Northbound database, that asks
>to change the source IP address of a packet from an IP address of
> @@ -3674,14 +3703,18 @@ nd_ns {
>options, then the action would be ip4/6.src=
>(B).
>  
> +  
>  
> +  
>  
>If the NAT rule has allowed_ext_ips configured, then
>there is an additional match ip4.dst == allowed_ext_ips
>. Similarly, for IPV6, match would be ip6.dst ==
>allowed_ext_ips.
>  
> +  
>  
> +  
>  
>If the NAT rule has exempted_ext_ips set, then
>there is an additional flow configured at the priority + 1 of
> @@ -3690,7 +3723,9 @@ nd_ns {
>. This flow is used to bypass the ct_snat action for a 
> packet
>which is destinted to exempted_ext_ips.
>  
> 

[ovs-dev] [PATCH ovn v3] northd: Provide the Gateway router option 'lb_force_snat_ip' to take router port ips.

2021-02-18 Thread numans
From: Numan Siddique 

When a Gateway router is configured with a load balancer
and it is also configured with options:lb_force_snat_ip=,
OVN after load balancing the destination IP to one of the
backend also does a NAT on the source ip with the
lb_force_snat_ip if the packet is destined to a load balancer
VIP.

There is a problem with the snat of source ip to 'lb_force_snat_ip'
in one particular usecase.  When the packet enters the Gateway router
from a provider logical switch destined to the load balancer VIP,
then it is first load balanced to one of the backend and then
the source ip is snatted to 'lb_force_snat_ip'.  If the chosen
backend is reachable via the provider logical switch, then the
packet is hairpinned back and it may hit the wire with
the source ip 'lb_force_snat_ip'.  If 'lb_force_snat_ip' happens
to be an OVN internal IP then the packet may be dropped.

This patch addresses this issue by providing the option to
set the option - 'lb_force_snat_ip=router_ip'.  If 'router_ip'
is set, then OVN will snat the load balanced packet to the
router ip of the logical router port which is chosen as 'outport'
in lr_in_ip_routing stage.

Example.

If the gateway router is

ovn-nbctl show lr0
router 68f20092-5563-44b8-9ccb-b11de3e3a66c (lr0)
port lr0-sw0
mac: "00:00:00:00:ff:01"
networks: ["10.0.0.1/24"]
port lr0-public
mac: "00:00:20:20:12:13"
networks: ["172.168.0.100/24"]

Then the below logical flows are added if 'lb_force_snat_ip'
is configured to 'router_ip'.

table=1 (lr_out_snat), priority=110
   match=(flags.force_snat_for_lb == 1 && ip4 && outport == "lr0-public"),
   action=(ct_snat(172.168.0.100);)

table=1 (lr_out_snat), priority=110
   match=(flags.force_snat_for_lb == 1 && ip4 && outport == "lr0-sw0")
   action=(ct_snat(10.0.0.1);)

For the above described scenario, the packet will have source ip as
172.168.0.100 which belongs to the provider logical switch CIDR.

Reported-by: Tim Rozet 
Signed-off-by: Numan Siddique 
---
 northd/ovn-northd.8.xml | 35 
 northd/ovn-northd.c | 91 +
 ovn-nb.xml  | 33 ++-
 tests/ovn-northd.at | 79 +++
 4 files changed, 220 insertions(+), 18 deletions(-)

diff --git a/northd/ovn-northd.8.xml b/northd/ovn-northd.8.xml
index 2f8b4e8c30..1d8f5edee1 100644
--- a/northd/ovn-northd.8.xml
+++ b/northd/ovn-northd.8.xml
@@ -3654,6 +3654,32 @@ nd_ns {
   flags.force_snat_for_dnat == 1  ip with an
   action ct_snat(B);.
 
+  
+
+  
+
+  If the Gateway router in the OVN Northbound database has been
+  configured to force SNAT a packet (that has been previously
+  load-balanced) using router IP (i.e :lb_force_snat_ip=router_ip), then for
+  each logical router port P attached to the Gateway
+  router, a priority-110 flow matches
+  flags.force_snat_for_lb == 1  outport == P
+   with an action ct_snat(R);
+  where R is the IP configured on the router port.
+  If R is an IPv4 address then the match will also
+  include ip4 and if it is an IPv6 address, then the
+  match will also include ip6.
+
+
+
+  If the logical router port P is configured with multiple
+  IPv4 and multiple IPv6 addresses, only the first IPv4 and first IPv6
+  address is considered.
+
+  
+
+  
 
   If the Gateway router in the OVN Northbound database has been
   configured to force SNAT a packet (that has been previously
@@ -3661,6 +3687,9 @@ nd_ns {
   flags.force_snat_for_lb == 1  ip with an
   action ct_snat(B);.
 
+  
+
+  
 
   For each configuration in the OVN Northbound database, that asks
   to change the source IP address of a packet from an IP address of
@@ -3674,14 +3703,18 @@ nd_ns {
   options, then the action would be ip4/6.src=
   (B).
 
+  
 
+  
 
   If the NAT rule has allowed_ext_ips configured, then
   there is an additional match ip4.dst == allowed_ext_ips
   . Similarly, for IPV6, match would be ip6.dst ==
   allowed_ext_ips.
 
+  
 
+  
 
   If the NAT rule has exempted_ext_ips set, then
   there is an additional flow configured at the priority + 1 of
@@ -3690,7 +3723,9 @@ nd_ns {
   . This flow is used to bypass the ct_snat action for a packet
   which is destinted to exempted_ext_ips.
 
+  
 
+  
 
   A priority-0 logical flow with match 1 has actions
   next;.
diff --git a/northd/ovn-northd.c b/northd/ovn-northd.c
index 39d7987820..0bbe92c09d 100644
--- a/northd/ovn-northd.c
+++ b/northd/ovn-northd.c
@@ -624,6 +624,7 @@ struct ovn_datapath {
 
 struct lport_addresses dnat_force_snat_addrs;

[ovs-dev] [PATCH ovn v10.1 0/6] Add DDlog implementation of ovn-northd

2021-02-18 Thread Ben Pfaff
v10.1:
  - Fold in fix to northd makefile.

v10:
  - Fix linking problem reported by Dumitru and others.
  - Update to ddlog 0.36.0 (thanks Leonid!).
  - Port OVN commits up to 858d1dd716db ("ofctrl: Fix the assert seen when 
flood removing flows.")
  - Fix IGMP and MLD snoop/querier/reply tests (thanks Dumitru!).
  - New commit "ovn-sb: Allow Multicast_Group to have empty set of ports."
  - New commit "ovn-northd: Simplify logic in build_bfd_table()."
  - New commit "tests: Wait for updates in "check BFD config propagation to 
BFD" test."

v9:
  - Add ddlog.stamp to BUILT_SOURCES, to fix the dependencies "for sure".
  - Rebase against ovn/master.
  - Port commit fdf295d5eb3a ("pinctrl: Honor
always_learn_from_arp_request for self created MAC_Bindings.")
  - Update to work with and require v2 of the ovsdb-cs library (see
https://mail.openvswitch.org/pipermail/ovs-dev/2020-December/378180.html).
  - All non-skipped tests pass, although some are still racy.
  - This is also available as the ddlog14 branch here:
https://github.com/blp/ovs-reviews/commits/ddlog14
  - Haven't done performance tests.  I aim to do that for v10.

v8:
  - Rebase against latest ovn master.
  - Port commit f9cab11d5fab ("Allow explicit setting of the SNAT zone
on a gateway router.")
  - Port commit f1119c125765 ("northd: Refactor load balancer vip parsing.")
  - Port commit 1dd27ea7aea4 ("Provide the option to pin
ovn-controller and ovn-northd to a specific version.").
  - Port commit 880dca99eaf7 ("northd: Enhance the implementation of
ACL log meters (pre-ddlog merge).")
  - Make ovn-northd-ddlog use the new ovsdb-cs (client sync) library
proposed for OVS
(https://mail.openvswitch.org/pipermail/ovs-dev/2020-November/377828.html).
In addition to eliminating duplicated code, this should make it
able to connect to a raft cluster.
  - Further improvements to test improvement patch (mostly added "check"s
and AS_BOX(...) to announce parts of a test)
  - Modernize some of the ddlog code a bit, e.g. by using the method-like
calls such as foo.get("key") in place of map_get(foo, "key").

v7:
  - Fixed "make dist" (thanks to Numan for reporting this.)
  - Fix probe interval setting (thanks to Numan again).
  - Small amount of improvement of OVN DDlog code (use lambdas in more places).
  - Fine-tuning of ovn-northd-ddlog code for jsonrpc session usage.
  - Fix newline issues in tests reported by Dumitru.
  - Add ack from Dumitru.

v6:
  - Applied and dropped patch for "test a == b".
  - Applied and dropped patch to allow more args to wait_for_row_count().
  - Applied and dropped ARP/ND broadcast test improvement patch.
  - Fix whitespace in patch to export ddlog_warn() and ddlog_err().

v5:
  - Drop patch for ACL log meters (this was included in v4.1 by mistake).
  - In addition to waiting for database, also wait for ports to come up.
  - New patch to support more arguments to wait_for_row_count that waiting
for ports indirectly needed.
  - Port commit c29221d9322a ("Allow VLAN traffic when LS:vlan-passthru=true").
  - Port commit 36a8745de859 ("Add support for DHCP options 28 (Broadcast 
Address)")
  - Add patch to improve "ARP/ND request broadcast limiting" test.

v4:
  - Fix dependencies for parallel build.
  - Fix spelling error in documentation.
  - Use --wait=sb, not --wait=hv, when no chassis are running.
  - Fixed IGMP and MLD tests by porting commit 9d2e8d32fb98
("ofctrl.c: Fix duplicated flow handling in I-P while merging
opposite changes."), which I had missed before.


Ben Pfaff (4):
  tests: Prepare for multiple northd types.
  tests: Wait for updates in "check BFD config propagation to BFD" test.
  ovn-northd: Simplify logic in build_bfd_table().
  ovn-sb: Allow Multicast_Group to have empty set of ports.

Leonid Ryzhyk (2):
  Export `VLOG_WARN` and `VLOG_ERR` from libovn for use in ddlog
  ovn-northd-ddlog: New implementation of ovn-northd based on ddlog.

 Documentation/automake.mk |2 +
 Documentation/intro/install/general.rst   |   31 +-
 Documentation/topics/debugging-ddlog.rst  |  280 +
 Documentation/topics/index.rst|1 +
 Documentation/tutorials/ddlog-new-feature.rst |  362 +
 Documentation/tutorials/index.rst |1 +
 NEWS  |6 +
 TODO.rst  |6 +
 acinclude.m4  |   43 +
 build-aux/automake.mk |1 +
 build-aux/libtool-deps|   35 +
 configure.ac  |5 +
 lib/ovn-util.c|   15 +
 lib/ovn-util.h|5 +
 m4/ovn.m4 |   16 +
 northd/.gitignore |4 +
 northd/automake.mk|  108 +
 northd/helpers.dl |   96 +
 northd/ipam.dl  

Re: [ovs-dev] [PATCH ovn v10 6/6] ovn-northd-ddlog: New implementation of ovn-northd based on ddlog.

2021-02-18 Thread Ben Pfaff
This had a bug in the makefile.  I fixed it:
https://github.com/blp/ovs-reviews/actions/runs/579105628
I'll post a v10.1.
___
dev mailing list
d...@openvswitch.org
https://mail.openvswitch.org/mailman/listinfo/ovs-dev


[ovs-dev] [PATCH ovn v2] ofctrl: Do not link a desired flow twice.

2021-02-18 Thread Dumitru Ceara
Depending on the logical flow matches, multiple SB flows can point to
the same desired flow.  If it happens that the desired flow conflicts
with a more restrictive (already installed) flow, then we shouldn't try
to add the desired flow multiple times to the list maintained for the
installed flow.

Fixes: 6f0b1e02d9ab ("ofctrl: Incremental processing for flow installation by 
tracking.")
Signed-off-by: Dumitru Ceara 
---
Note: I'm quite sure about the "Fixes" tag above, however, I couldn't
reproduce the issue without the following commit:
  dadae4f800cc ("ofctrl.c: Only merge actions for conjunctive flows.")

v2:
- Address Mark's comments:
  - readd log message removed by accident.
  - add comments to the new test.
---
 controller/ofctrl.c |  2 +-
 tests/ovn.at| 23 +++
 2 files changed, 24 insertions(+), 1 deletion(-)

diff --git a/controller/ofctrl.c b/controller/ofctrl.c
index 1c9694a..415d9b7 100644
--- a/controller/ofctrl.c
+++ b/controller/ofctrl.c
@@ -1989,7 +1989,7 @@ update_installed_flows_by_track(struct 
ovn_desired_flow_table *flow_table,
  * tracked, so it must have been modified. */
 installed_flow_mod(>flow, >flow, msgs);
 ovn_flow_log(>flow, "updating installed (tracked)");
-} else {
+} else if (!f->installed_flow) {
 /* Adding a new flow that conflicts with an existing installed
  * flow, so add it to the link.  If this flow becomes active,
  * e.g., it is less restrictive than the previous active flow
diff --git a/tests/ovn.at b/tests/ovn.at
index 344e6bf..3d027c4 100644
--- a/tests/ovn.at
+++ b/tests/ovn.at
@@ -13955,6 +13955,29 @@ AT_CHECK([as hv1 ovs-ofctl dump-flows br-int table=45 
| ofctl_strip_all | \
  table=45, priority=1003,ip,metadata=0x1,nw_src=10.0.0.42 actions=conjunction()
 ])
 
+# Add another ACL that overlaps with the existing less restrictive ones.
+check ovn-nbctl acl-add ls1 to-lport 3 'udp || ((ip4.src==10.0.0.1 || 
ip4.src==10.0.0.2) && (ip4.dst == 10.0.0.3 || ip4.dst == 10.0.0.4))' allow
+check ovn-nbctl --wait=hv sync
+
+# Check OVS flows, the same conjunctive flows as above should still be there,
+# with an additional conjunction action.
+#
+# New non-conjunctive flows should be added to match on 'udp'.
+AT_CHECK([as hv1 ovs-ofctl dump-flows br-int table=45 | ofctl_strip_all | \
+   grep "priority=1003" | \
+   sed 's/conjunction([[^)]]*)/conjunction()/g' | sort], [0], [dnl
+ table=45, priority=1003,conj_id=2,ip,metadata=0x1 actions=resubmit(,46)
+ table=45, priority=1003,conj_id=3,ip,metadata=0x1 actions=resubmit(,46)
+ table=45, priority=1003,conj_id=4,ip,metadata=0x1 actions=resubmit(,46)
+ table=45, priority=1003,ip,metadata=0x1,nw_dst=10.0.0.3 
actions=conjunction(),conjunction(),conjunction()
+ table=45, priority=1003,ip,metadata=0x1,nw_dst=10.0.0.4 
actions=conjunction(),conjunction(),conjunction()
+ table=45, priority=1003,ip,metadata=0x1,nw_src=10.0.0.1 actions=resubmit(,46)
+ table=45, priority=1003,ip,metadata=0x1,nw_src=10.0.0.2 
actions=conjunction(),conjunction()
+ table=45, priority=1003,ip,metadata=0x1,nw_src=10.0.0.42 actions=conjunction()
+ table=45, priority=1003,udp,metadata=0x1 actions=resubmit(,46)
+ table=45, priority=1003,udp6,metadata=0x1 actions=resubmit(,46)
+])
+
 OVN_CLEANUP([hv1])
 AT_CLEANUP
 
-- 
1.8.3.1

___
dev mailing list
d...@openvswitch.org
https://mail.openvswitch.org/mailman/listinfo/ovs-dev


Re: [ovs-dev] [PATCH ovn] northd: Provide the Gateway router option 'lb_force_snat_ip' to take router port ips.

2021-02-18 Thread Numan Siddique
On Thu, Feb 18, 2021 at 11:56 PM Mark Gray  wrote:
>
> On 18/02/2021 17:26, Numan Siddique wrote:
> > On Thu, Feb 18, 2021 at 9:15 PM Mark Gray  wrote:
> >>
> >> On 18/02/2021 14:30, Numan Siddique wrote:
> >>> On Wed, Feb 17, 2021 at 7:37 PM Mark Gray  wrote:
> 
>  Thanks Numan, some suggestions below!
> >>>
> >>> Hi Mark G,
> >>>
> >>> Thanks for the review.
> >>>
> >>> PSB for a few comments.
> >>>
> 
>  On 09/02/2021 18:44, num...@ovn.org wrote:
> > From: Numan Siddique 
> >
> > When a Gateway router is configured with a load balancer
> > and it is also configured with options:lb_force_snat_ip=,
> > OVN after load balancing the destination IP to one of the
> > backend also does a NAT on the source ip with the
> > lb_force_snat_ip if the packet is destined to a load balancer
> > VIP.
> >
> > There is a problem with the snat of source ip to 'lb_force_snat_ip'
> > in one particular usecase.  When the packet enters the Gateway router
> > from a provider logical switch destined to the load balancer VIP,
> > then it is first load balanced to one of the backend and then
> > the source ip is snatted to 'lb_force_snat_ip'.  If the chosen
> > backend is reachable via the provider logical switch, then the
> > packet is hairpinned back and it may hit the wire with
> > the source ip 'lb_force_snat_ip'.  If 'lb_force_snat_ip' happens
> > to be an OVN internal IP then the packet may be dropped.
> >
> > This patch addresses this issue by providing the option to
> > set the option - 'lb_force_snat_ip=router_ip'.  If 'router_ip'
> > is set, then OVN will snat the load balanced packet to the
> > router ip of the logical router port which chosen as 'outport'
> > in lr_in_ip_routing stage.
> 
>  It almost feels like this should be the default behaviour?
> >>>
> >>>
> >>> Can you please elaborate more ? You mean ideally CMS should set
> >>> - router_ip ?
> >>
> >> I was thinking that it could just be lb_force_snat_ip=true (default to
> >> remote_ip)?
> >
> > You mean 'router_ip' ?  If it is 'true' then, IMHO, it is not clear with 
> > what IP
> > to snat with.
> >
> > Since lb_force_snat_ip can take other IP addresses (which is the present 
> > case),
> > I am not sure if mixing bool/string would be clear enough for the user.
> >
> > Let me know if you think it is obvious that it will be router ip if set to 
> > true.
>
> Let me rephrase. Is there a use case in which IP should be specified?
> However, thinking about it more, I think I have answered myself, it
> could be that if a link had multiple IPs, you would want to specify
> which IP it should take.

Also right now with the present master, we do support IP for lb_force_snat_ip

An example - https://github.com/ovn-org/ovn/blob/master/tests/ovn.at#L22669

Ok. Let me know if you are fine with the patch If I do the other changes ?
I can definitely spin up another version if you prefer.

Thanks
Numan

>
> >
> > Thanks
> > Numan
> >
> >
> >>>
> >>>
> >
> > Example.
> >
> > If the gateway router is
> >
> > ovn-nbctl show lr0
> > router 68f20092-5563-44b8-9ccb-b11de3e3a66c (lr0)
> > port lr0-sw0
> > mac: "00:00:00:00:ff:01"
> > networks: ["10.0.0.1/24"]
> > port lr0-public
> > mac: "00:00:20:20:12:13"
> > networks: ["172.168.0.100/24"]
> >
> > Then the below logical flows are added if 'lb_force_snat_ip'
> > is configured to 'router_ip'.
> >
> > table=1 (lr_out_snat), priority=110
> >match=(flags.force_snat_for_lb == 1 && ip4 && outport == 
> > "lr0-public"),
> >action=(ct_snat(172.168.0.100);)
> >
> > table=1 (lr_out_snat), priority=110
> >match=(flags.force_snat_for_lb == 1 && ip4 && outport == "lr0-sw0")
> >action=(ct_snat(10.0.0.1);)
> >
> > For the above described scenario, the packet will have source ip as
> > 172.168.0.100 which belongs to the provider logical switch CIDR.
> >
> > Reported-by: Tim Rozet 
> > Signed-off-by: Numan Siddique 
> > ---
> >  northd/ovn-northd.8.xml | 35 ++
> >  northd/ovn-northd.c | 66 --
> >  tests/ovn-northd.at | 79 +
> >  3 files changed, 177 insertions(+), 3 deletions(-)
> >
> > diff --git a/northd/ovn-northd.8.xml b/northd/ovn-northd.8.xml
> > index 70065a36d9..27b28aff93 100644
> > --- a/northd/ovn-northd.8.xml
> > +++ b/northd/ovn-northd.8.xml
> 
>  Should 'ovn-nb.xml' also be updated?
> >>>
> >>> Great catch. I totally missed it.
> >>>
> 
> > @@ -3653,6 +3653,32 @@ nd_ns {
> >flags.force_snat_for_dnat == 1  ip 
> > with an
> >action ct_snat(B);.
> >  
> > +  
> > +
> > +  
> > +
> > +  If the Gateway 

[ovs-dev] [RFC PATCH ovn] binding: Do not try to incrementally process former VIF updates.

2021-02-18 Thread Dumitru Ceara
If a Port_Binding corresponding to a VIF changes in the Southbound to
represent a port that cannot be bound locally (e.g., localport,
localnet, patch) then ovn-controller should not try to process this
update incrementally.  If it would try, it would need to first remove
cleanup all previous lbindings from memory which is not trivial.

Failing to do so might cause ovn-controller to access already freed
memory later on.

However, because this is an unlikely scenario, to avoid over
complicating the incremental processing engine, we now rely to a regular
recompute when such Port_Binding updates are detected.

This implies though that when the runtime_data I-P node is updated we
also need to recompute physical flows to make sure that flows for
specific types of ports, e.g., localports, are properly installed.

To reproduce the issue, this patch also modifies the "ovn -- 2 HVs, 1
lport/HV, localport ports" test.  More tests are added for all types of
port bindings that shouldn't be claimed locally.

Fixes: 354bdba51abf ("ovn-controller: I-P for SB port binding and OVS interface 
in runtime_data.")
Signed-off-by: Dumitru Ceara 
---
Note: sending this patch as RFC for now because I'm not completely sure
if the physical_run() call in the I-P engine can be avoided.
---
 controller/binding.c| 32 
 controller/ovn-controller.c |  2 ++
 tests/ovn.at| 59 -
 3 files changed, 87 insertions(+), 6 deletions(-)

diff --git a/controller/binding.c b/controller/binding.c
index efaa109..9ce5c01 100644
--- a/controller/binding.c
+++ b/controller/binding.c
@@ -1027,6 +1027,17 @@ is_lbinding_container_parent(struct local_binding 
*lbinding)
 }
 
 static bool
+is_non_local_port_bound(const struct sbrec_port_binding *pb,
+enum en_lport_type lport_type)
+{
+if (lport_type == LP_PATCH || lport_type == LP_LOCALNET ||
+lport_type == LP_LOCALPORT) {
+return !!pb->chassis;
+}
+return false;
+}
+
+static bool
 release_local_binding_children(const struct sbrec_chassis *chassis_rec,
struct local_binding *lbinding,
bool sb_readonly,
@@ -1486,9 +1497,17 @@ binding_run(struct binding_ctx_in *b_ctx_in, struct 
binding_ctx_out *b_ctx_out)
b_ctx_in->port_binding_table) {
 enum en_lport_type lport_type = get_lport_type(pb);
 
+if (is_non_local_port_bound(pb, lport_type)) {
+release_lport(pb, !b_ctx_in->ovnsb_idl_txn, NULL);
+}
+
 switch (lport_type) {
 case LP_PATCH:
+update_local_lport_ids(pb, b_ctx_out);
+break;
 case LP_LOCALPORT:
+update_local_lport_ids(pb, b_ctx_out);
+break;
 case LP_VTEP:
 update_local_lport_ids(pb, b_ctx_out);
 break;
@@ -1818,6 +1837,12 @@ consider_iface_claim(const struct ovsrec_interface 
*iface_rec,
 }
 
 if (lbinding->pb) {
+enum en_lport_type lport_type = get_lport_type(lbinding->pb);
+
+if (lport_type != LP_VIF && lport_type != LP_VIRTUAL) {
+return true;
+}
+
 if (!consider_vif_lport(lbinding->pb, b_ctx_in, b_ctx_out,
 lbinding, qos_map)) {
 return false;
@@ -2419,6 +2444,13 @@ delete_done:
 break;
 }
 
+/* Former VIFs that changed to non-local ports should be released,
+ * but we cannot handle this incrementally.
+ */
+if (is_non_local_port_bound(pb, lport_type)) {
+handled = false;
+}
+
 if (!handled) {
 break;
 }
diff --git a/controller/ovn-controller.c b/controller/ovn-controller.c
index 4343650..15c78db 100644
--- a/controller/ovn-controller.c
+++ b/controller/ovn-controller.c
@@ -2306,6 +2306,8 @@ flow_output_runtime_data_handler(struct engine_node *node,
 struct physical_ctx p_ctx;
 init_physical_ctx(node, rt_data, _ctx);
 
+physical_run(_ctx, >flow_table);
+
 struct tracked_binding_datapath *tdp;
 HMAP_FOR_EACH (tdp, node, tracked_dp_bindings) {
 if (tdp->is_new) {
diff --git a/tests/ovn.at b/tests/ovn.at
index 344e6bf..b3a8b03 100644
--- a/tests/ovn.at
+++ b/tests/ovn.at
@@ -11319,11 +11319,6 @@ ovn_start
 
 ovn-nbctl ls-add ls1
 
-# Add localport to the switch
-ovn-nbctl lsp-add ls1 lp01
-ovn-nbctl lsp-set-addresses lp01 f0:00:00:00:00:01
-ovn-nbctl lsp-set-type lp01 localport
-
 net_add n1
 
 for i in 1 2; do
@@ -11350,10 +11345,17 @@ for i in 1 2; do
 OVS_WAIT_UNTIL([test x`ovn-nbctl lsp-get-up lp${i}1` = xup])
 done
 
+# Add localport to the switch
+ovn-nbctl lsp-add ls1 lp01
+ovn-nbctl lsp-set-addresses lp01 f0:00:00:00:00:01
+ovn-nbctl lsp-set-type lp01 localport
+
 wait_for_ports_up
-ovn-nbctl --wait=sb sync
+ovn-nbctl --wait=hv sync
 ovn-sbctl dump-flows
 
+check_column "" Port_Binding 

Re: [ovs-dev] [PATCH ovn] northd: Provide the Gateway router option 'lb_force_snat_ip' to take router port ips.

2021-02-18 Thread Mark Gray
On 18/02/2021 17:26, Numan Siddique wrote:
> On Thu, Feb 18, 2021 at 9:15 PM Mark Gray  wrote:
>>
>> On 18/02/2021 14:30, Numan Siddique wrote:
>>> On Wed, Feb 17, 2021 at 7:37 PM Mark Gray  wrote:

 Thanks Numan, some suggestions below!
>>>
>>> Hi Mark G,
>>>
>>> Thanks for the review.
>>>
>>> PSB for a few comments.
>>>

 On 09/02/2021 18:44, num...@ovn.org wrote:
> From: Numan Siddique 
>
> When a Gateway router is configured with a load balancer
> and it is also configured with options:lb_force_snat_ip=,
> OVN after load balancing the destination IP to one of the
> backend also does a NAT on the source ip with the
> lb_force_snat_ip if the packet is destined to a load balancer
> VIP.
>
> There is a problem with the snat of source ip to 'lb_force_snat_ip'
> in one particular usecase.  When the packet enters the Gateway router
> from a provider logical switch destined to the load balancer VIP,
> then it is first load balanced to one of the backend and then
> the source ip is snatted to 'lb_force_snat_ip'.  If the chosen
> backend is reachable via the provider logical switch, then the
> packet is hairpinned back and it may hit the wire with
> the source ip 'lb_force_snat_ip'.  If 'lb_force_snat_ip' happens
> to be an OVN internal IP then the packet may be dropped.
>
> This patch addresses this issue by providing the option to
> set the option - 'lb_force_snat_ip=router_ip'.  If 'router_ip'
> is set, then OVN will snat the load balanced packet to the
> router ip of the logical router port which chosen as 'outport'
> in lr_in_ip_routing stage.

 It almost feels like this should be the default behaviour?
>>>
>>>
>>> Can you please elaborate more ? You mean ideally CMS should set
>>> - router_ip ?
>>
>> I was thinking that it could just be lb_force_snat_ip=true (default to
>> remote_ip)?
> 
> You mean 'router_ip' ?  If it is 'true' then, IMHO, it is not clear with what 
> IP
> to snat with.
> 
> Since lb_force_snat_ip can take other IP addresses (which is the present 
> case),
> I am not sure if mixing bool/string would be clear enough for the user.
> 
> Let me know if you think it is obvious that it will be router ip if set to 
> true.

Let me rephrase. Is there a use case in which IP should be specified?
However, thinking about it more, I think I have answered myself, it
could be that if a link had multiple IPs, you would want to specify
which IP it should take.

> 
> Thanks
> Numan
> 
> 
>>>
>>>
>
> Example.
>
> If the gateway router is
>
> ovn-nbctl show lr0
> router 68f20092-5563-44b8-9ccb-b11de3e3a66c (lr0)
> port lr0-sw0
> mac: "00:00:00:00:ff:01"
> networks: ["10.0.0.1/24"]
> port lr0-public
> mac: "00:00:20:20:12:13"
> networks: ["172.168.0.100/24"]
>
> Then the below logical flows are added if 'lb_force_snat_ip'
> is configured to 'router_ip'.
>
> table=1 (lr_out_snat), priority=110
>match=(flags.force_snat_for_lb == 1 && ip4 && outport == "lr0-public"),
>action=(ct_snat(172.168.0.100);)
>
> table=1 (lr_out_snat), priority=110
>match=(flags.force_snat_for_lb == 1 && ip4 && outport == "lr0-sw0")
>action=(ct_snat(10.0.0.1);)
>
> For the above described scenario, the packet will have source ip as
> 172.168.0.100 which belongs to the provider logical switch CIDR.
>
> Reported-by: Tim Rozet 
> Signed-off-by: Numan Siddique 
> ---
>  northd/ovn-northd.8.xml | 35 ++
>  northd/ovn-northd.c | 66 --
>  tests/ovn-northd.at | 79 +
>  3 files changed, 177 insertions(+), 3 deletions(-)
>
> diff --git a/northd/ovn-northd.8.xml b/northd/ovn-northd.8.xml
> index 70065a36d9..27b28aff93 100644
> --- a/northd/ovn-northd.8.xml
> +++ b/northd/ovn-northd.8.xml

 Should 'ovn-nb.xml' also be updated?
>>>
>>> Great catch. I totally missed it.
>>>

> @@ -3653,6 +3653,32 @@ nd_ns {
>flags.force_snat_for_dnat == 1  ip with 
> an
>action ct_snat(B);.
>  
> +  
> +
> +  
> +
> +  If the Gateway router in the OVN Northbound database has been
> +  configured to force SNAT a packet (that has been previously
> +  load-balanced) using router IP (i.e  +  table="Logical_Router"/>:lb_force_snat_ip=router_ip), then for
> +  each logical router port P attached to the Gateway
> +  router, a priority-110 flow matches
> +  flags.force_snat_for_lb == 1  outport == 
> P
> +   with an action ct_snat(R);
> +  where R is the router port IP configured.

 maybe rephrase to "is the IP configured on the router 

Re: [ovs-dev] [PATCH ovn v2] northd: Provide the Gateway router option 'lb_force_snat_ip' to take router port ips.

2021-02-18 Thread Numan Siddique
On Thu, Feb 18, 2021 at 10:57 PM Mark Gray  wrote:
>
> On 18/02/2021 17:21, Numan Siddique wrote:
> > On Thu, Feb 18, 2021 at 9:08 PM Mark Gray  wrote:
> >>
> >> On 18/02/2021 14:30, num...@ovn.org wrote:
> >>> From: Numan Siddique 
> >>>
> >>> When a Gateway router is configured with a load balancer
> >>> and it is also configured with options:lb_force_snat_ip=,
> >>> OVN after load balancing the destination IP to one of the
> >>> backend also does a NAT on the source ip with the
> >>> lb_force_snat_ip if the packet is destined to a load balancer
> >>> VIP.
> >>>
> >>> There is a problem with the snat of source ip to 'lb_force_snat_ip'
> >>> in one particular usecase.  When the packet enters the Gateway router
> >>> from a provider logical switch destined to the load balancer VIP,
> >>> then it is first load balanced to one of the backend and then
> >>> the source ip is snatted to 'lb_force_snat_ip'.  If the chosen
> >>> backend is reachable via the provider logical switch, then the
> >>> packet is hairpinned back and it may hit the wire with
> >>> the source ip 'lb_force_snat_ip'.  If 'lb_force_snat_ip' happens
> >>> to be an OVN internal IP then the packet may be dropped.
> >>>
> >>> This patch addresses this issue by providing the option to
> >>> set the option - 'lb_force_snat_ip=router_ip'.  If 'router_ip'
> >>> is set, then OVN will snat the load balanced packet to the
> >>> router ip of the logical router port which is chosen as 'outport'
> >>> in lr_in_ip_routing stage.
> >>>
> >>> Example.
> >>>
> >>> If the gateway router is
> >>>
> >>> ovn-nbctl show lr0
> >>> router 68f20092-5563-44b8-9ccb-b11de3e3a66c (lr0)
> >>> port lr0-sw0
> >>> mac: "00:00:00:00:ff:01"
> >>> networks: ["10.0.0.1/24"]
> >>> port lr0-public
> >>> mac: "00:00:20:20:12:13"
> >>> networks: ["172.168.0.100/24"]
> >>>
> >>> Then the below logical flows are added if 'lb_force_snat_ip'
> >>> is configured to 'router_ip'.
> >>>
> >>> table=1 (lr_out_snat), priority=110
> >>>match=(flags.force_snat_for_lb == 1 && ip4 && outport == "lr0-public"),
> >>>action=(ct_snat(172.168.0.100);)
> >>>
> >>> table=1 (lr_out_snat), priority=110
> >>>match=(flags.force_snat_for_lb == 1 && ip4 && outport == "lr0-sw0")
> >>>action=(ct_snat(10.0.0.1);)
> >>>
> >>> For the above described scenario, the packet will have source ip as
> >>> 172.168.0.100 which belongs to the provider logical switch CIDR.
> >>>
> >>> Reported-by: Tim Rozet 
> >>> Signed-off-by: Numan Siddique 
> >>> ---
> >>>
> >>> v1 -> v2
> >>> ---
> >>>   * Addressed review comments from Mark Gray.
> >>>
> >>>  northd/ovn-northd.8.xml | 35 
> >>>  northd/ovn-northd.c | 93 +
> >>>  ovn-nb.xml  | 33 ++-
> >>>  tests/ovn-northd.at | 79 ++
> >>>  4 files changed, 222 insertions(+), 18 deletions(-)
> >>>
> >>> diff --git a/northd/ovn-northd.8.xml b/northd/ovn-northd.8.xml
> >>> index 2f8b4e8c30..1d8f5edee1 100644
> >>> --- a/northd/ovn-northd.8.xml
> >>> +++ b/northd/ovn-northd.8.xml
> >>> @@ -3654,6 +3654,32 @@ nd_ns {
> >>>flags.force_snat_for_dnat == 1  ip with 
> >>> an
> >>>action ct_snat(B);.
> >>>  
> >>> +  
> >>> +
> >>> +  
> >>> +
> >>> +  If the Gateway router in the OVN Northbound database has been
> >>> +  configured to force SNAT a packet (that has been previously
> >>> +  load-balanced) using router IP (i.e  >>> +  table="Logical_Router"/>:lb_force_snat_ip=router_ip), then for
> >>> +  each logical router port P attached to the Gateway
> >>> +  router, a priority-110 flow matches
> >>> +  flags.force_snat_for_lb == 1  outport == 
> >>> P
> >>> +   with an action ct_snat(R);
> >>> +  where R is the IP configured on the router port.
> >>> +  If R is an IPv4 address then the match will also
> >>> +  include ip4 and if it is an IPv6 address, then the
> >>> +  match will also include ip6.
> >>> +
> >>> +
> >>> +
> >>> +  If the logical router port P is configured with 
> >>> multiple
> >>> +  IPv4 and multiple IPv6 addresses, only the first IPv4 and 
> >>> first IPv6
> >>> +  address is considered.
> >>> +
> >>> +  
> >>> +
> >>> +  
> >>>  
> >>>If the Gateway router in the OVN Northbound database has been
> >>>configured to force SNAT a packet (that has been previously
> >>> @@ -3661,6 +3687,9 @@ nd_ns {
> >>>flags.force_snat_for_lb == 1  ip with an
> >>>action ct_snat(B);.
> >>>  
> >>> +  
> >>> +
> >>> +  
> >>>  
> >>>For each configuration in the OVN Northbound database, that 
> >>> asks
> >>>to change the source IP address of a packet from an IP address 
> >>> of
> >>> @@ -3674,14 +3703,18 @@ 

Re: [ovs-dev] [PATCH ovn branch-20.06 00/15] Backport rollup

2021-02-18 Thread Frode Nordahl
On Thu, Feb 18, 2021 at 10:34 AM Dumitru Ceara  wrote:
>
> On 2/18/21 9:09 AM, Frode Nordahl wrote:
> > Hello all,
>
> Hi Frode,
>
> Many thanks for this!

You're very welcome, thank you for all the bits!

> >
> > In Ubuntu we have backported a set of fixes to our OVN 20.06 and OVN
> > 20.03 packages.  In preparing for new point releases for OVN 20.06
> > and OVN 20.03, we would very much like to add these patches to the
> > upstream branches.
> >
> > The issues solved for OVN 20.06 with these patches are:
> >
> >* Fix for upgrading database schema of clustered databases on package
> >  upgrade (LP: #1907081)[0]
> >* Fixes for predictable resolution for conflicting flow actions.
> >  (LP: #1906922)[1]
>
> You might want to wait a bit with releasing new packages and include
> more patches (some are not merged in upstream master yet) that fix
> crashes due some of the ofctrl changes:
>
> https://github.com/ovn-org/ovn/commit/858d1dd716db1a1e664a7c1737fd34f04fcbda5e
> (in upstream master and branch20.12)
>
> http://patchwork.ozlabs.org/project/ovn/patch/1613490806-11143-1-git-send-email-dce...@redhat.com/
> (I'll be submitting a v2 today).

Thank you for bringing those to my attention, we'll monitor those closely.

We have had this code running in the wild in select deployments for
months without any issues so far, the updated packages have also been
in our proposed pockets for an extended period before being shipped
today.

So while we really should get these fixes in as soon as possible,
luckily it does not appear to happen too often in the wild.

I'll work towards getting these backported too so that we can consume
them from a point release update.

-- 
Frode Nordahl

> Regards,
> Dumitru
>
___
dev mailing list
d...@openvswitch.org
https://mail.openvswitch.org/mailman/listinfo/ovs-dev


Re: [ovs-dev] [PATCH ovn v2] northd: Provide the Gateway router option 'lb_force_snat_ip' to take router port ips.

2021-02-18 Thread Mark Gray
On 18/02/2021 17:21, Numan Siddique wrote:
> On Thu, Feb 18, 2021 at 9:08 PM Mark Gray  wrote:
>>
>> On 18/02/2021 14:30, num...@ovn.org wrote:
>>> From: Numan Siddique 
>>>
>>> When a Gateway router is configured with a load balancer
>>> and it is also configured with options:lb_force_snat_ip=,
>>> OVN after load balancing the destination IP to one of the
>>> backend also does a NAT on the source ip with the
>>> lb_force_snat_ip if the packet is destined to a load balancer
>>> VIP.
>>>
>>> There is a problem with the snat of source ip to 'lb_force_snat_ip'
>>> in one particular usecase.  When the packet enters the Gateway router
>>> from a provider logical switch destined to the load balancer VIP,
>>> then it is first load balanced to one of the backend and then
>>> the source ip is snatted to 'lb_force_snat_ip'.  If the chosen
>>> backend is reachable via the provider logical switch, then the
>>> packet is hairpinned back and it may hit the wire with
>>> the source ip 'lb_force_snat_ip'.  If 'lb_force_snat_ip' happens
>>> to be an OVN internal IP then the packet may be dropped.
>>>
>>> This patch addresses this issue by providing the option to
>>> set the option - 'lb_force_snat_ip=router_ip'.  If 'router_ip'
>>> is set, then OVN will snat the load balanced packet to the
>>> router ip of the logical router port which is chosen as 'outport'
>>> in lr_in_ip_routing stage.
>>>
>>> Example.
>>>
>>> If the gateway router is
>>>
>>> ovn-nbctl show lr0
>>> router 68f20092-5563-44b8-9ccb-b11de3e3a66c (lr0)
>>> port lr0-sw0
>>> mac: "00:00:00:00:ff:01"
>>> networks: ["10.0.0.1/24"]
>>> port lr0-public
>>> mac: "00:00:20:20:12:13"
>>> networks: ["172.168.0.100/24"]
>>>
>>> Then the below logical flows are added if 'lb_force_snat_ip'
>>> is configured to 'router_ip'.
>>>
>>> table=1 (lr_out_snat), priority=110
>>>match=(flags.force_snat_for_lb == 1 && ip4 && outport == "lr0-public"),
>>>action=(ct_snat(172.168.0.100);)
>>>
>>> table=1 (lr_out_snat), priority=110
>>>match=(flags.force_snat_for_lb == 1 && ip4 && outport == "lr0-sw0")
>>>action=(ct_snat(10.0.0.1);)
>>>
>>> For the above described scenario, the packet will have source ip as
>>> 172.168.0.100 which belongs to the provider logical switch CIDR.
>>>
>>> Reported-by: Tim Rozet 
>>> Signed-off-by: Numan Siddique 
>>> ---
>>>
>>> v1 -> v2
>>> ---
>>>   * Addressed review comments from Mark Gray.
>>>
>>>  northd/ovn-northd.8.xml | 35 
>>>  northd/ovn-northd.c | 93 +
>>>  ovn-nb.xml  | 33 ++-
>>>  tests/ovn-northd.at | 79 ++
>>>  4 files changed, 222 insertions(+), 18 deletions(-)
>>>
>>> diff --git a/northd/ovn-northd.8.xml b/northd/ovn-northd.8.xml
>>> index 2f8b4e8c30..1d8f5edee1 100644
>>> --- a/northd/ovn-northd.8.xml
>>> +++ b/northd/ovn-northd.8.xml
>>> @@ -3654,6 +3654,32 @@ nd_ns {
>>>flags.force_snat_for_dnat == 1  ip with an
>>>action ct_snat(B);.
>>>  
>>> +  
>>> +
>>> +  
>>> +
>>> +  If the Gateway router in the OVN Northbound database has been
>>> +  configured to force SNAT a packet (that has been previously
>>> +  load-balanced) using router IP (i.e >> +  table="Logical_Router"/>:lb_force_snat_ip=router_ip), then for
>>> +  each logical router port P attached to the Gateway
>>> +  router, a priority-110 flow matches
>>> +  flags.force_snat_for_lb == 1  outport == 
>>> P
>>> +   with an action ct_snat(R);
>>> +  where R is the IP configured on the router port.
>>> +  If R is an IPv4 address then the match will also
>>> +  include ip4 and if it is an IPv6 address, then the
>>> +  match will also include ip6.
>>> +
>>> +
>>> +
>>> +  If the logical router port P is configured with 
>>> multiple
>>> +  IPv4 and multiple IPv6 addresses, only the first IPv4 and first 
>>> IPv6
>>> +  address is considered.
>>> +
>>> +  
>>> +
>>> +  
>>>  
>>>If the Gateway router in the OVN Northbound database has been
>>>configured to force SNAT a packet (that has been previously
>>> @@ -3661,6 +3687,9 @@ nd_ns {
>>>flags.force_snat_for_lb == 1  ip with an
>>>action ct_snat(B);.
>>>  
>>> +  
>>> +
>>> +  
>>>  
>>>For each configuration in the OVN Northbound database, that asks
>>>to change the source IP address of a packet from an IP address of
>>> @@ -3674,14 +3703,18 @@ nd_ns {
>>>options, then the action would be ip4/6.src=
>>>(B).
>>>  
>>> +  
>>>
>>> +  
>>>  
>>>If the NAT rule has allowed_ext_ips configured, then
>>>there is an additional match ip4.dst == 
>>> allowed_ext_ips
>>>. Similarly, for 

Re: [ovs-dev] [PATCH ovn] northd: Provide the Gateway router option 'lb_force_snat_ip' to take router port ips.

2021-02-18 Thread Numan Siddique
On Thu, Feb 18, 2021 at 9:15 PM Mark Gray  wrote:
>
> On 18/02/2021 14:30, Numan Siddique wrote:
> > On Wed, Feb 17, 2021 at 7:37 PM Mark Gray  wrote:
> >>
> >> Thanks Numan, some suggestions below!
> >
> > Hi Mark G,
> >
> > Thanks for the review.
> >
> > PSB for a few comments.
> >
> >>
> >> On 09/02/2021 18:44, num...@ovn.org wrote:
> >>> From: Numan Siddique 
> >>>
> >>> When a Gateway router is configured with a load balancer
> >>> and it is also configured with options:lb_force_snat_ip=,
> >>> OVN after load balancing the destination IP to one of the
> >>> backend also does a NAT on the source ip with the
> >>> lb_force_snat_ip if the packet is destined to a load balancer
> >>> VIP.
> >>>
> >>> There is a problem with the snat of source ip to 'lb_force_snat_ip'
> >>> in one particular usecase.  When the packet enters the Gateway router
> >>> from a provider logical switch destined to the load balancer VIP,
> >>> then it is first load balanced to one of the backend and then
> >>> the source ip is snatted to 'lb_force_snat_ip'.  If the chosen
> >>> backend is reachable via the provider logical switch, then the
> >>> packet is hairpinned back and it may hit the wire with
> >>> the source ip 'lb_force_snat_ip'.  If 'lb_force_snat_ip' happens
> >>> to be an OVN internal IP then the packet may be dropped.
> >>>
> >>> This patch addresses this issue by providing the option to
> >>> set the option - 'lb_force_snat_ip=router_ip'.  If 'router_ip'
> >>> is set, then OVN will snat the load balanced packet to the
> >>> router ip of the logical router port which chosen as 'outport'
> >>> in lr_in_ip_routing stage.
> >>
> >> It almost feels like this should be the default behaviour?
> >
> >
> > Can you please elaborate more ? You mean ideally CMS should set
> > - router_ip ?
>
> I was thinking that it could just be lb_force_snat_ip=true (default to
> remote_ip)?

You mean 'router_ip' ?  If it is 'true' then, IMHO, it is not clear with what IP
to snat with.

Since lb_force_snat_ip can take other IP addresses (which is the present case),
I am not sure if mixing bool/string would be clear enough for the user.

Let me know if you think it is obvious that it will be router ip if set to true.

Thanks
Numan


> >
> >
> >>>
> >>> Example.
> >>>
> >>> If the gateway router is
> >>>
> >>> ovn-nbctl show lr0
> >>> router 68f20092-5563-44b8-9ccb-b11de3e3a66c (lr0)
> >>> port lr0-sw0
> >>> mac: "00:00:00:00:ff:01"
> >>> networks: ["10.0.0.1/24"]
> >>> port lr0-public
> >>> mac: "00:00:20:20:12:13"
> >>> networks: ["172.168.0.100/24"]
> >>>
> >>> Then the below logical flows are added if 'lb_force_snat_ip'
> >>> is configured to 'router_ip'.
> >>>
> >>> table=1 (lr_out_snat), priority=110
> >>>match=(flags.force_snat_for_lb == 1 && ip4 && outport == "lr0-public"),
> >>>action=(ct_snat(172.168.0.100);)
> >>>
> >>> table=1 (lr_out_snat), priority=110
> >>>match=(flags.force_snat_for_lb == 1 && ip4 && outport == "lr0-sw0")
> >>>action=(ct_snat(10.0.0.1);)
> >>>
> >>> For the above described scenario, the packet will have source ip as
> >>> 172.168.0.100 which belongs to the provider logical switch CIDR.
> >>>
> >>> Reported-by: Tim Rozet 
> >>> Signed-off-by: Numan Siddique 
> >>> ---
> >>>  northd/ovn-northd.8.xml | 35 ++
> >>>  northd/ovn-northd.c | 66 --
> >>>  tests/ovn-northd.at | 79 +
> >>>  3 files changed, 177 insertions(+), 3 deletions(-)
> >>>
> >>> diff --git a/northd/ovn-northd.8.xml b/northd/ovn-northd.8.xml
> >>> index 70065a36d9..27b28aff93 100644
> >>> --- a/northd/ovn-northd.8.xml
> >>> +++ b/northd/ovn-northd.8.xml
> >>
> >> Should 'ovn-nb.xml' also be updated?
> >
> > Great catch. I totally missed it.
> >
> >>
> >>> @@ -3653,6 +3653,32 @@ nd_ns {
> >>>flags.force_snat_for_dnat == 1  ip with 
> >>> an
> >>>action ct_snat(B);.
> >>>  
> >>> +  
> >>> +
> >>> +  
> >>> +
> >>> +  If the Gateway router in the OVN Northbound database has been
> >>> +  configured to force SNAT a packet (that has been previously
> >>> +  load-balanced) using router IP (i.e  >>> +  table="Logical_Router"/>:lb_force_snat_ip=router_ip), then for
> >>> +  each logical router port P attached to the Gateway
> >>> +  router, a priority-110 flow matches
> >>> +  flags.force_snat_for_lb == 1  outport == 
> >>> P
> >>> +   with an action ct_snat(R);
> >>> +  where R is the router port IP configured.
> >>
> >> maybe rephrase to "is the IP configured on the router port."
> >
> > Ack. done
> >
> >>
> >>> +  If R is an IPv4 address then the match will also
> >>> +  include ip4 and if it is an IPv6 address, then the
> >>> +  match will also include ip6.
> >>> +
> >>> +
> >>> +
> >>> +  If the logical router port P is configured with 
> 

Re: [ovs-dev] [PATCH ovn v2] northd: Provide the Gateway router option 'lb_force_snat_ip' to take router port ips.

2021-02-18 Thread Numan Siddique
On Thu, Feb 18, 2021 at 9:08 PM Mark Gray  wrote:
>
> On 18/02/2021 14:30, num...@ovn.org wrote:
> > From: Numan Siddique 
> >
> > When a Gateway router is configured with a load balancer
> > and it is also configured with options:lb_force_snat_ip=,
> > OVN after load balancing the destination IP to one of the
> > backend also does a NAT on the source ip with the
> > lb_force_snat_ip if the packet is destined to a load balancer
> > VIP.
> >
> > There is a problem with the snat of source ip to 'lb_force_snat_ip'
> > in one particular usecase.  When the packet enters the Gateway router
> > from a provider logical switch destined to the load balancer VIP,
> > then it is first load balanced to one of the backend and then
> > the source ip is snatted to 'lb_force_snat_ip'.  If the chosen
> > backend is reachable via the provider logical switch, then the
> > packet is hairpinned back and it may hit the wire with
> > the source ip 'lb_force_snat_ip'.  If 'lb_force_snat_ip' happens
> > to be an OVN internal IP then the packet may be dropped.
> >
> > This patch addresses this issue by providing the option to
> > set the option - 'lb_force_snat_ip=router_ip'.  If 'router_ip'
> > is set, then OVN will snat the load balanced packet to the
> > router ip of the logical router port which is chosen as 'outport'
> > in lr_in_ip_routing stage.
> >
> > Example.
> >
> > If the gateway router is
> >
> > ovn-nbctl show lr0
> > router 68f20092-5563-44b8-9ccb-b11de3e3a66c (lr0)
> > port lr0-sw0
> > mac: "00:00:00:00:ff:01"
> > networks: ["10.0.0.1/24"]
> > port lr0-public
> > mac: "00:00:20:20:12:13"
> > networks: ["172.168.0.100/24"]
> >
> > Then the below logical flows are added if 'lb_force_snat_ip'
> > is configured to 'router_ip'.
> >
> > table=1 (lr_out_snat), priority=110
> >match=(flags.force_snat_for_lb == 1 && ip4 && outport == "lr0-public"),
> >action=(ct_snat(172.168.0.100);)
> >
> > table=1 (lr_out_snat), priority=110
> >match=(flags.force_snat_for_lb == 1 && ip4 && outport == "lr0-sw0")
> >action=(ct_snat(10.0.0.1);)
> >
> > For the above described scenario, the packet will have source ip as
> > 172.168.0.100 which belongs to the provider logical switch CIDR.
> >
> > Reported-by: Tim Rozet 
> > Signed-off-by: Numan Siddique 
> > ---
> >
> > v1 -> v2
> > ---
> >   * Addressed review comments from Mark Gray.
> >
> >  northd/ovn-northd.8.xml | 35 
> >  northd/ovn-northd.c | 93 +
> >  ovn-nb.xml  | 33 ++-
> >  tests/ovn-northd.at | 79 ++
> >  4 files changed, 222 insertions(+), 18 deletions(-)
> >
> > diff --git a/northd/ovn-northd.8.xml b/northd/ovn-northd.8.xml
> > index 2f8b4e8c30..1d8f5edee1 100644
> > --- a/northd/ovn-northd.8.xml
> > +++ b/northd/ovn-northd.8.xml
> > @@ -3654,6 +3654,32 @@ nd_ns {
> >flags.force_snat_for_dnat == 1  ip with an
> >action ct_snat(B);.
> >  
> > +  
> > +
> > +  
> > +
> > +  If the Gateway router in the OVN Northbound database has been
> > +  configured to force SNAT a packet (that has been previously
> > +  load-balanced) using router IP (i.e  > +  table="Logical_Router"/>:lb_force_snat_ip=router_ip), then for
> > +  each logical router port P attached to the Gateway
> > +  router, a priority-110 flow matches
> > +  flags.force_snat_for_lb == 1  outport == 
> > P
> > +   with an action ct_snat(R);
> > +  where R is the IP configured on the router port.
> > +  If R is an IPv4 address then the match will also
> > +  include ip4 and if it is an IPv6 address, then the
> > +  match will also include ip6.
> > +
> > +
> > +
> > +  If the logical router port P is configured with 
> > multiple
> > +  IPv4 and multiple IPv6 addresses, only the first IPv4 and first 
> > IPv6
> > +  address is considered.
> > +
> > +  
> > +
> > +  
> >  
> >If the Gateway router in the OVN Northbound database has been
> >configured to force SNAT a packet (that has been previously
> > @@ -3661,6 +3687,9 @@ nd_ns {
> >flags.force_snat_for_lb == 1  ip with an
> >action ct_snat(B);.
> >  
> > +  
> > +
> > +  
> >  
> >For each configuration in the OVN Northbound database, that asks
> >to change the source IP address of a packet from an IP address of
> > @@ -3674,14 +3703,18 @@ nd_ns {
> >options, then the action would be ip4/6.src=
> >(B).
> >  
> > +  
> >
> > +  
> >  
> >If the NAT rule has allowed_ext_ips configured, then
> >there is an additional match ip4.dst == 
> > allowed_ext_ips
> >. Similarly, for IPV6, match would be ip6.dst 
> > ==
> >

Re: [ovs-dev] [PATCHv2] Documentation: Fix DPDK qos example.

2021-02-18 Thread Eelco Chaudron



On 18 Feb 2021, at 16:24, William Tu wrote:

> Fix the example use case based on the decription.
> EIR and CIR are measured in bytes/sec and considered 64-byte
> IP packets size withtout 14-byte Ethernet header.
> So fix the 1000pps example by: (64 - 14) * 1000 = 50,000
> If the frame includes 4-byte FCS header, then it's
> (64 - 14 - 4) * 1000 = 46,000
>
> Fixes: e61bdffc2a98 ("netdev-dpdk: Add new DPDK RFC 4115 egress policer")
> Signed-off-by: William Tu 

Looks good, thanks for taking the time to fix this!

Acked-by: Eelco Chaudron 

___
dev mailing list
d...@openvswitch.org
https://mail.openvswitch.org/mailman/listinfo/ovs-dev


[ovs-dev] [PATCH ovn] binding: Fix potential crash when binding_seqno_run is skipped.

2021-02-18 Thread Dumitru Ceara
The prerequisite for binding_seqno_run() is that it has to be called
while there are valid SB and OVS transactions available.

ovn-controller's main() function respects that but that means that there
is a small window (when OVS transaction is still in progress) when port
bindings might be deleted from the Southbound.

When binding_seqno_run() was finally called, it was asserting that the
Port_bindings to still exist.  This check is too restrictive and the
solution is to just skip bindings that have become partial (i.e., no
SB.Port_Binding or no OVS.Interface).

Fixes: 4d3cb42b076b ("binding: Set Logical_Switch_Port.up when all OVS flows 
are installed.")
Reported-at: https://bugzilla.redhat.com/1930030
Reported-by: Numan Siddique 
Signed-off-by: Dumitru Ceara 
---
Note: the window to reproduce the issue is quite narrow so I didn't
manage to write a test that would hit the issue consistently.
---
 controller/binding.c | 14 --
 1 file changed, 8 insertions(+), 6 deletions(-)

diff --git a/controller/binding.c b/controller/binding.c
index efaa109..2b19fd0 100644
--- a/controller/binding.c
+++ b/controller/binding.c
@@ -2498,13 +2498,15 @@ binding_seqno_run(struct shash *local_bindings)
 SSET_FOR_EACH_SAFE (iface_id, iface_id_next, _iface_bound_set) {
 struct shash_node *lb_node = shash_find(local_bindings, iface_id);
 
-if (lb_node) {
-/* This is a newly bound interface, make sure we reset the
- * Port_Binding 'up' field and the OVS Interface 'external-id'.
- */
-struct local_binding *lb = lb_node->data;
+struct local_binding *lb = lb_node ? lb_node->data : NULL;
 
-ovs_assert(lb->pb && lb->iface);
+/* Make sure the binding is still complete, i.e., both SB port_binding
+ * and OVS interface still exist.
+ *
+ * If so, then this is a newly bound interface, make sure we reset the
+ * Port_Binding 'up' field and the OVS Interface 'external-id'.
+ */
+if (lb && lb->pb && lb->iface) {
 new_ifaces = true;
 
 if (smap_get(>iface->external_ids, OVN_INSTALLED_EXT_ID)) {
-- 
1.8.3.1

___
dev mailing list
d...@openvswitch.org
https://mail.openvswitch.org/mailman/listinfo/ovs-dev


Re: [ovs-dev] [PATCH V2 00/14] Netdev vxlan-decap offload

2021-02-18 Thread Kovacevic, Marko
<...> 
> Sending to Marko. As he wasn't subscribed to ovs-dev then.
> 
<...>
> > VXLAN decap in OVS-DPDK configuration consists of two flows:
> > F1: in_port(ens1f0),eth(),ipv4(),udp(), actions:tnl_pop(vxlan_sys_4789)
> > F2: tunnel(),in_port(vxlan_sys_4789),eth(),ipv4(), actions:ens1f0_0
> >
> > F1 is a classification flow. It has outer headers matches and it classifies 
> > the
> > packet as a VXLAN packet, and using tnl_pop action the packet continues
> > processing in F2.
> > F2 is a flow that has matches on tunnel metadata as well as on the inner
> > packet headers (as any other flow).
> >
<...>

Hi Eli,

Hi,
After testing the patchset it seems  after the tenth patch I start seeing a 
drop in the scatter performance around ~4% decrease  across all packet sizes 
tested(112,256,512,1518)
Burst measurement see a decrease also but not as much as the scatter does.

Patch10
fff1f9168 netdev-offload-dpdk: Support tunnel pop action

The test used for this is a 32 virito-user ports with 1Millions flows.

Traffic @ Phy NIC Rx:
Ether()/IP()/UDP()/VXLAN()/Ether()/IP()

Burst: on the outer ip we do a burst of 32 packets with same ip then switch for 
next 32 and so on 
Scatter: for scatter we do incrementally for 32 
And on the inner packet we have a total of  1048576 flows

I can send on a diagram directly just restricted with html here to send the 
diagram here of the test setup

Thanks 
Marko K
___
dev mailing list
d...@openvswitch.org
https://mail.openvswitch.org/mailman/listinfo/ovs-dev


[ovs-dev] [PATCH ovn v3] ovn-controller: Split logical flow and phsyical flow processing.

2021-02-18 Thread numans
From: Numan Siddique 

Presently, the 'flow_output' engine node recomputes
physical flows by calling physical_run() in the
'physical_flow_changes' handler.in some scenarios.
Because of this, an engine run can do a full recompute
of physical flows but not full recompute of logical flows.
Although this works now, it is problematic as the same
desired flow table is used for both physical and logical flows.

This patch now separates the handling of logical flows and
physical flows.  Two separate engine nodes are added -
lflow_output and pflow_output with their own flow tables and
these two nodes are now inputs to the main engine node -
flow_output.

CC: Han Zhou 
Signed-off-by: Numan Siddique 
---

v2 -> v3
-
  * Rebased to resolve conflicts.

v1 -> v2
-
  * Rebased to resolve conflicts.

 TODO.rst|   6 +
 controller/lflow.c  |  14 +-
 controller/lflow.h  |   6 +-
 controller/ofctrl.c | 215 +++
 controller/ofctrl.h |  37 +-
 controller/ovn-controller.c | 691 ++--
 controller/physical.c   |  28 +-
 controller/physical.h   |  12 +-
 8 files changed, 543 insertions(+), 466 deletions(-)

diff --git a/TODO.rst b/TODO.rst
index c15815539f..910531e7e3 100644
--- a/TODO.rst
+++ b/TODO.rst
@@ -160,3 +160,9 @@ OVN To-do List
 to find a way of determining if routing has already been executed (on a
 different hypervisor) for the IP multicast packet being processed locally
 in the router pipeline.
+
+* ovn-controller Incremental processing
+
+  * physical.c has a global simap -localvif_to_ofport which stores the
+local OVS interfaces and the ofport numbers. Move this to the engine data
+of the engine data node - ed_type_pflow_output.
diff --git a/controller/lflow.c b/controller/lflow.c
index 4bdd953bee..8b1e4770ba 100644
--- a/controller/lflow.c
+++ b/controller/lflow.c
@@ -966,7 +966,7 @@ static void
 consider_neighbor_flow(struct ovsdb_idl_index *sbrec_port_binding_by_name,
const struct hmap *local_datapaths,
const struct sbrec_mac_binding *b,
-   struct ovn_desired_flow_table *flow_table)
+   struct ovn_flow_table *flow_table)
 {
 const struct sbrec_port_binding *pb
 = lport_lookup_by_name(sbrec_port_binding_by_name, b->logical_port);
@@ -1046,7 +1046,7 @@ static void
 add_neighbor_flows(struct ovsdb_idl_index *sbrec_port_binding_by_name,
const struct sbrec_mac_binding_table *mac_binding_table,
const struct hmap *local_datapaths,
-   struct ovn_desired_flow_table *flow_table)
+   struct ovn_flow_table *flow_table)
 {
 const struct sbrec_mac_binding *b;
 SBREC_MAC_BINDING_TABLE_FOR_EACH (b, mac_binding_table) {
@@ -1232,7 +1232,7 @@ add_lb_vip_hairpin_flows(struct ovn_controller_lb *lb,
  struct ovn_lb_vip *lb_vip,
  struct ovn_lb_backend *lb_backend,
  uint8_t lb_proto,
- struct ovn_desired_flow_table *flow_table)
+ struct ovn_flow_table *flow_table)
 {
 uint64_t stub[1024 / 8];
 struct ofpbuf ofpacts = OFPBUF_STUB_INITIALIZER(stub);
@@ -1301,7 +1301,7 @@ static void
 add_lb_ct_snat_vip_flows(struct ovn_controller_lb *lb,
  struct ovn_lb_vip *lb_vip,
  uint8_t lb_proto,
- struct ovn_desired_flow_table *flow_table)
+ struct ovn_flow_table *flow_table)
 {
 uint64_t stub[1024 / 8];
 struct ofpbuf ofpacts = OFPBUF_STUB_INITIALIZER(stub);
@@ -1369,7 +1369,7 @@ add_lb_ct_snat_vip_flows(struct ovn_controller_lb *lb,
 static void
 consider_lb_hairpin_flows(const struct sbrec_load_balancer *sbrec_lb,
   const struct hmap *local_datapaths,
-  struct ovn_desired_flow_table *flow_table)
+  struct ovn_flow_table *flow_table)
 {
 /* Check if we need to add flows or not.  If there is one datapath
  * in the local_datapaths, it means all the datapaths of the lb
@@ -1417,7 +1417,7 @@ consider_lb_hairpin_flows(const struct 
sbrec_load_balancer *sbrec_lb,
 static void
 add_lb_hairpin_flows(const struct sbrec_load_balancer_table *lb_table,
  const struct hmap *local_datapaths,
- struct ovn_desired_flow_table *flow_table)
+ struct ovn_flow_table *flow_table)
 {
 const struct sbrec_load_balancer *lb;
 SBREC_LOAD_BALANCER_TABLE_FOR_EACH (lb, lb_table) {
@@ -1431,7 +1431,7 @@ lflow_handle_changed_neighbors(
 struct ovsdb_idl_index *sbrec_port_binding_by_name,
 const struct sbrec_mac_binding_table *mac_binding_table,
 const struct hmap *local_datapaths,
-struct ovn_desired_flow_table *flow_table)
+struct ovn_flow_table *flow_table)
 {
 const 

Re: [ovs-dev] [PATCH ovn] northd: Provide the Gateway router option 'lb_force_snat_ip' to take router port ips.

2021-02-18 Thread Mark Gray
On 18/02/2021 14:30, Numan Siddique wrote:
> On Wed, Feb 17, 2021 at 7:37 PM Mark Gray  wrote:
>>
>> Thanks Numan, some suggestions below!
> 
> Hi Mark G,
> 
> Thanks for the review.
> 
> PSB for a few comments.
> 
>>
>> On 09/02/2021 18:44, num...@ovn.org wrote:
>>> From: Numan Siddique 
>>>
>>> When a Gateway router is configured with a load balancer
>>> and it is also configured with options:lb_force_snat_ip=,
>>> OVN after load balancing the destination IP to one of the
>>> backend also does a NAT on the source ip with the
>>> lb_force_snat_ip if the packet is destined to a load balancer
>>> VIP.
>>>
>>> There is a problem with the snat of source ip to 'lb_force_snat_ip'
>>> in one particular usecase.  When the packet enters the Gateway router
>>> from a provider logical switch destined to the load balancer VIP,
>>> then it is first load balanced to one of the backend and then
>>> the source ip is snatted to 'lb_force_snat_ip'.  If the chosen
>>> backend is reachable via the provider logical switch, then the
>>> packet is hairpinned back and it may hit the wire with
>>> the source ip 'lb_force_snat_ip'.  If 'lb_force_snat_ip' happens
>>> to be an OVN internal IP then the packet may be dropped.
>>>
>>> This patch addresses this issue by providing the option to
>>> set the option - 'lb_force_snat_ip=router_ip'.  If 'router_ip'
>>> is set, then OVN will snat the load balanced packet to the
>>> router ip of the logical router port which chosen as 'outport'
>>> in lr_in_ip_routing stage.
>>
>> It almost feels like this should be the default behaviour?
> 
> 
> Can you please elaborate more ? You mean ideally CMS should set
> - router_ip ?

I was thinking that it could just be lb_force_snat_ip=true (default to
remote_ip)?
> 
> 
>>>
>>> Example.
>>>
>>> If the gateway router is
>>>
>>> ovn-nbctl show lr0
>>> router 68f20092-5563-44b8-9ccb-b11de3e3a66c (lr0)
>>> port lr0-sw0
>>> mac: "00:00:00:00:ff:01"
>>> networks: ["10.0.0.1/24"]
>>> port lr0-public
>>> mac: "00:00:20:20:12:13"
>>> networks: ["172.168.0.100/24"]
>>>
>>> Then the below logical flows are added if 'lb_force_snat_ip'
>>> is configured to 'router_ip'.
>>>
>>> table=1 (lr_out_snat), priority=110
>>>match=(flags.force_snat_for_lb == 1 && ip4 && outport == "lr0-public"),
>>>action=(ct_snat(172.168.0.100);)
>>>
>>> table=1 (lr_out_snat), priority=110
>>>match=(flags.force_snat_for_lb == 1 && ip4 && outport == "lr0-sw0")
>>>action=(ct_snat(10.0.0.1);)
>>>
>>> For the above described scenario, the packet will have source ip as
>>> 172.168.0.100 which belongs to the provider logical switch CIDR.
>>>
>>> Reported-by: Tim Rozet 
>>> Signed-off-by: Numan Siddique 
>>> ---
>>>  northd/ovn-northd.8.xml | 35 ++
>>>  northd/ovn-northd.c | 66 --
>>>  tests/ovn-northd.at | 79 +
>>>  3 files changed, 177 insertions(+), 3 deletions(-)
>>>
>>> diff --git a/northd/ovn-northd.8.xml b/northd/ovn-northd.8.xml
>>> index 70065a36d9..27b28aff93 100644
>>> --- a/northd/ovn-northd.8.xml
>>> +++ b/northd/ovn-northd.8.xml
>>
>> Should 'ovn-nb.xml' also be updated?
> 
> Great catch. I totally missed it.
> 
>>
>>> @@ -3653,6 +3653,32 @@ nd_ns {
>>>flags.force_snat_for_dnat == 1  ip with an
>>>action ct_snat(B);.
>>>  
>>> +  
>>> +
>>> +  
>>> +
>>> +  If the Gateway router in the OVN Northbound database has been
>>> +  configured to force SNAT a packet (that has been previously
>>> +  load-balanced) using router IP (i.e >> +  table="Logical_Router"/>:lb_force_snat_ip=router_ip), then for
>>> +  each logical router port P attached to the Gateway
>>> +  router, a priority-110 flow matches
>>> +  flags.force_snat_for_lb == 1  outport == 
>>> P
>>> +   with an action ct_snat(R);
>>> +  where R is the router port IP configured.
>>
>> maybe rephrase to "is the IP configured on the router port."
> 
> Ack. done
> 
>>
>>> +  If R is an IPv4 address then the match will also
>>> +  include ip4 and if it is an IPv6 address, then the
>>> +  match will also include ip6.
>>> +
>>> +
>>> +
>>> +  If the logical router port P is configured with 
>>> multiple
>>> +  IPv4 and multiple IPv6 addresses, only the first IPv4 and first 
>>> IPv6
>>> +  address is considered.
>>
>> Should we log this condition?
> 
> Ack. I have added the log for this in v2.
> 
> 
>>
>>> +
>>> +  
>>> +
>>> +  
>>>  
>>>If the Gateway router in the OVN Northbound database has been
>>>configured to force SNAT a packet (that has been previously
>>> @@ -3660,6 +3686,9 @@ nd_ns {
>>>flags.force_snat_for_lb == 1  ip with an
>>>action ct_snat(B);.
>>>  
>>> +  
>>> +
>>> +  
>>>  
>>>For 

Re: [ovs-dev] [PATCH ovn v2] northd: Provide the Gateway router option 'lb_force_snat_ip' to take router port ips.

2021-02-18 Thread Mark Gray
On 18/02/2021 14:30, num...@ovn.org wrote:
> From: Numan Siddique 
> 
> When a Gateway router is configured with a load balancer
> and it is also configured with options:lb_force_snat_ip=,
> OVN after load balancing the destination IP to one of the
> backend also does a NAT on the source ip with the
> lb_force_snat_ip if the packet is destined to a load balancer
> VIP.
> 
> There is a problem with the snat of source ip to 'lb_force_snat_ip'
> in one particular usecase.  When the packet enters the Gateway router
> from a provider logical switch destined to the load balancer VIP,
> then it is first load balanced to one of the backend and then
> the source ip is snatted to 'lb_force_snat_ip'.  If the chosen
> backend is reachable via the provider logical switch, then the
> packet is hairpinned back and it may hit the wire with
> the source ip 'lb_force_snat_ip'.  If 'lb_force_snat_ip' happens
> to be an OVN internal IP then the packet may be dropped.
> 
> This patch addresses this issue by providing the option to
> set the option - 'lb_force_snat_ip=router_ip'.  If 'router_ip'
> is set, then OVN will snat the load balanced packet to the
> router ip of the logical router port which is chosen as 'outport'
> in lr_in_ip_routing stage.
> 
> Example.
> 
> If the gateway router is
> 
> ovn-nbctl show lr0
> router 68f20092-5563-44b8-9ccb-b11de3e3a66c (lr0)
> port lr0-sw0
> mac: "00:00:00:00:ff:01"
> networks: ["10.0.0.1/24"]
> port lr0-public
> mac: "00:00:20:20:12:13"
> networks: ["172.168.0.100/24"]
> 
> Then the below logical flows are added if 'lb_force_snat_ip'
> is configured to 'router_ip'.
> 
> table=1 (lr_out_snat), priority=110
>match=(flags.force_snat_for_lb == 1 && ip4 && outport == "lr0-public"),
>action=(ct_snat(172.168.0.100);)
> 
> table=1 (lr_out_snat), priority=110
>match=(flags.force_snat_for_lb == 1 && ip4 && outport == "lr0-sw0")
>action=(ct_snat(10.0.0.1);)
> 
> For the above described scenario, the packet will have source ip as
> 172.168.0.100 which belongs to the provider logical switch CIDR.
> 
> Reported-by: Tim Rozet 
> Signed-off-by: Numan Siddique 
> ---
> 
> v1 -> v2
> ---
>   * Addressed review comments from Mark Gray.
> 
>  northd/ovn-northd.8.xml | 35 
>  northd/ovn-northd.c | 93 +
>  ovn-nb.xml  | 33 ++-
>  tests/ovn-northd.at | 79 ++
>  4 files changed, 222 insertions(+), 18 deletions(-)
> 
> diff --git a/northd/ovn-northd.8.xml b/northd/ovn-northd.8.xml
> index 2f8b4e8c30..1d8f5edee1 100644
> --- a/northd/ovn-northd.8.xml
> +++ b/northd/ovn-northd.8.xml
> @@ -3654,6 +3654,32 @@ nd_ns {
>flags.force_snat_for_dnat == 1  ip with an
>action ct_snat(B);.
>  
> +  
> +
> +  
> +
> +  If the Gateway router in the OVN Northbound database has been
> +  configured to force SNAT a packet (that has been previously
> +  load-balanced) using router IP (i.e  +  table="Logical_Router"/>:lb_force_snat_ip=router_ip), then for
> +  each logical router port P attached to the Gateway
> +  router, a priority-110 flow matches
> +  flags.force_snat_for_lb == 1  outport == 
> P
> +   with an action ct_snat(R);
> +  where R is the IP configured on the router port.
> +  If R is an IPv4 address then the match will also
> +  include ip4 and if it is an IPv6 address, then the
> +  match will also include ip6.
> +
> +
> +
> +  If the logical router port P is configured with multiple
> +  IPv4 and multiple IPv6 addresses, only the first IPv4 and first 
> IPv6
> +  address is considered.
> +
> +  
> +
> +  
>  
>If the Gateway router in the OVN Northbound database has been
>configured to force SNAT a packet (that has been previously
> @@ -3661,6 +3687,9 @@ nd_ns {
>flags.force_snat_for_lb == 1  ip with an
>action ct_snat(B);.
>  
> +  
> +
> +  
>  
>For each configuration in the OVN Northbound database, that asks
>to change the source IP address of a packet from an IP address of
> @@ -3674,14 +3703,18 @@ nd_ns {
>options, then the action would be ip4/6.src=
>(B).
>  
> +  
>  
> +  
>  
>If the NAT rule has allowed_ext_ips configured, then
>there is an additional match ip4.dst == allowed_ext_ips
>. Similarly, for IPV6, match would be ip6.dst ==
>allowed_ext_ips.
>  
> +  
>  
> +  
>  
>If the NAT rule has exempted_ext_ips set, then
>there is an additional flow configured at the priority + 1 of
> @@ -3690,7 +3723,9 @@ nd_ns {
>. This flow is used to bypass the ct_snat action for a 
> 

[ovs-dev] [PATCHv2] Documentation: Fix DPDK qos example.

2021-02-18 Thread William Tu
Fix the example use case based on the decription.
EIR and CIR are measured in bytes/sec and considered 64-byte
IP packets size withtout 14-byte Ethernet header.
So fix the 1000pps example by: (64 - 14) * 1000 = 50,000
If the frame includes 4-byte FCS header, then it's
(64 - 14 - 4) * 1000 = 46,000

Fixes: e61bdffc2a98 ("netdev-dpdk: Add new DPDK RFC 4115 egress policer")
Signed-off-by: William Tu 
---
 Documentation/topics/dpdk/qos.rst | 14 --
 vswitchd/vswitch.xml  |  6 --
 2 files changed, 12 insertions(+), 8 deletions(-)

diff --git a/Documentation/topics/dpdk/qos.rst 
b/Documentation/topics/dpdk/qos.rst
index 103495415a9c..a98ec672fcf5 100644
--- a/Documentation/topics/dpdk/qos.rst
+++ b/Documentation/topics/dpdk/qos.rst
@@ -69,22 +69,24 @@ to prioritize certain traffic over others at a port level.
 
 For example, the following configuration will limit the traffic rate at a
 port level to a maximum of 2000 packets a second (64 bytes IPv4 packets).
-100pps as CIR (Committed Information Rate) and 1000pps as EIR (Excess
-Information Rate). High priority traffic is routed to queue 10, which marks
+1000pps as CIR (Committed Information Rate) and 1000pps as EIR (Excess
+Information Rate). CIR and EIR are measured in bytes without Ethernet header.
+As a result, 1000pps means (64-byte - 14-byte) * 1000 = 50,000 in the
+configuration below. High priority traffic is routed to queue 10, which marks
 all traffic as CIR, i.e. Green. All low priority traffic, queue 20, is
 marked as EIR, i.e. Yellow::
 
 $ ovs-vsctl --timeout=5 set port dpdk1 qos=@myqos -- \
 --id=@myqos create qos type=trtcm-policer \
-other-config:cir=52000 other-config:cbs=2048 \
-other-config:eir=52000 other-config:ebs=2048  \
+other-config:cir=5 other-config:cbs=2048 \
+other-config:eir=5 other-config:ebs=2048  \
 queues:10=@dpdk1Q10 queues:20=@dpdk1Q20 -- \
  --id=@dpdk1Q10 create queue \
-  other-config:cir=4160 other-config:cbs=2048 \
+  other-config:cir=10 other-config:cbs=2048 \
   other-config:eir=0 other-config:ebs=0 -- \
  --id=@dpdk1Q20 create queue \
other-config:cir=0 other-config:cbs=0 \
-   other-config:eir=4160 other-config:ebs=2048 \
+   other-config:eir=5 other-config:ebs=2048
 
 This configuration accomplishes that the high priority traffic has a
 guaranteed bandwidth egressing the ports at CIR (1000pps), but it can also
diff --git a/vswitchd/vswitch.xml b/vswitchd/vswitch.xml
index a2ad84edefa9..4597a215d936 100644
--- a/vswitchd/vswitch.xml
+++ b/vswitchd/vswitch.xml
@@ -4660,7 +4660,8 @@ ovs-vsctl add-port br0 p0 -- set Interface p0 type=patch 
options:peer=p1 \
 packets per second the CIR would be set to to to 4600. This value
 can be broken into '1,000,000 x 46'. Where 1,000,000 is the policing
 rate for the number of packets per second and 46 represents the size
-of the packet data for a 64 byte ip packet.
+of the packet data for a 64 bytes IP packet without 14 bytes Ethernet
+and 4 bytes FCS header.
   
   
 The Committed Burst Size (CBS) is measured in bytes and represents a
@@ -4681,7 +4682,8 @@ ovs-vsctl add-port br0 p0 -- set Interface p0 type=patch 
options:peer=p1 \
 packets per second the EIR would be set to to to 4600. This value
 can be broken into '1,000,000 x 46'. Where 1,000,000 is the policing
 rate for the number of packets per second and 46 represents the size
-of the packet data for a 64 byte ip packet.
+of the packet data for a 64 bytes IP packet without 14 bytes Ethernet
+and 4 bytes FCS header.
   
   
 The Excess Burst Size (EBS) is measured in bytes and represents a
-- 
2.7.4

___
dev mailing list
d...@openvswitch.org
https://mail.openvswitch.org/mailman/listinfo/ovs-dev


Re: [ovs-dev] [PATCH] Documentation: Fix DPDK qos example.

2021-02-18 Thread William Tu
On Thu, Feb 18, 2021 at 6:55 AM Eelco Chaudron  wrote:
>
>
>
> On 18 Feb 2021, at 15:40, William Tu wrote:
>
> > On Thu, Feb 18, 2021 at 1:23 AM Eelco Chaudron 
> > wrote:
> >>
> >>
> >>
> >> On 17 Feb 2021, at 18:41, William Tu wrote:
> >>
> 
> >>  Information Rate). High priority traffic is routed to queue 10,
> >> which marks
> >>  all traffic as CIR, i.e. Green. All low priority traffic, queue
> >> 20,
> >> is
> >>  marked as EIR, i.e. Yellow::
> >>
> >>  $ ovs-vsctl --timeout=5 set port dpdk1 qos=@myqos -- \
> >>  --id=@myqos create qos type=trtcm-policer \
> >> -other-config:cir=52000 other-config:cbs=2048 \
> >> -other-config:eir=52000 other-config:ebs=2048  \
> 
>  52000 is fine as our documentation states cir, eir are in bytes per
>  second, minus the ethernet header.
>  So (64-12) * 1000 = 52000
> >>>
> >>> How come it's not minus 14-byte ethernet header?
> >>
> >> You are right, it should be 14, miscounted the rte_ether_hdr
> >> structure size :(
> >>
> > Thank you!
> > at vswitchd/vswitch.xml, it uses "46", should I change it to "64- 14 =
> > 50"?
> > calculated by (pps x packet data size).  For example assuming
> > a user
> > wishes to limit a stream consisting of 64 byte packets to 1
> > million
> > packets per second the EIR would be set to to to 4600.
> > This value
> > can be broken into '1,000,000 x 46'. Where 1,000,000 is the
> > policing
> > rate for the number of packets per second and 46 represents
> > the size
> > of the packet data for a 64 byte ip packet.
> > William
>
> Guess they take of the FCS also, so the packets they sent are 14 bytes
> ethernet, + 46 bytes IP + 4 FCS.

I see, thanks!

>
> In my tests I sent 64 byte packets, i.e. 14 bytes ethernet + 50 bytes
> IP.
>
> Maybe we should clarify this in the text some how?
>
Sure, I will do it.
William
___
dev mailing list
d...@openvswitch.org
https://mail.openvswitch.org/mailman/listinfo/ovs-dev


Re: [ovs-dev] [PATCH ovn v2] northd: Provide the Gateway router option 'lb_force_snat_ip' to take router port ips.

2021-02-18 Thread Numan Siddique
On Thu, Feb 18, 2021 at 8:31 PM 0-day Robot  wrote:
>
> Bleep bloop.  Greetings Numan Siddique, I am a robot and I have tried out 
> your patch.
> Thanks for your contribution.
>
> I encountered some error that I wasn't expecting.  See the details below.
>
>
> checkpatch:
> WARNING: Line is 94 characters long (recommended limit is 79)
> WARNING: Line has trailing whitespace
> #224 FILE: northd/ovn-northd.c:9001:
>   op->lrp_networks.ipv4_addrs[0].addr_s);
>
> WARNING: Line is 94 characters long (recommended limit is 79)
> WARNING: Line has trailing whitespace
> #249 FILE: northd/ovn-northd.c:9026:
>   op->lrp_networks.ipv6_addrs[0].addr_s);
>
> Lines checked: 399, Warnings: 4, Errors: 0

Sorry for these checkpatch warnings. Please ignore this during review.
I'll address them.

Thanks
Numan


>
>
> Please check this out.  If you feel there has been an error, please email 
> acon...@redhat.com
>
> Thanks,
> 0-day Robot
> ___
> dev mailing list
> d...@openvswitch.org
> https://mail.openvswitch.org/mailman/listinfo/ovs-dev
>
___
dev mailing list
d...@openvswitch.org
https://mail.openvswitch.org/mailman/listinfo/ovs-dev


Re: [ovs-dev] [PATCH ovn v2] northd: Provide the Gateway router option 'lb_force_snat_ip' to take router port ips.

2021-02-18 Thread 0-day Robot
Bleep bloop.  Greetings Numan Siddique, I am a robot and I have tried out your 
patch.
Thanks for your contribution.

I encountered some error that I wasn't expecting.  See the details below.


checkpatch:
WARNING: Line is 94 characters long (recommended limit is 79)
WARNING: Line has trailing whitespace
#224 FILE: northd/ovn-northd.c:9001:
  op->lrp_networks.ipv4_addrs[0].addr_s);   
  

WARNING: Line is 94 characters long (recommended limit is 79)
WARNING: Line has trailing whitespace
#249 FILE: northd/ovn-northd.c:9026:
  op->lrp_networks.ipv6_addrs[0].addr_s);   
  

Lines checked: 399, Warnings: 4, Errors: 0


Please check this out.  If you feel there has been an error, please email 
acon...@redhat.com

Thanks,
0-day Robot
___
dev mailing list
d...@openvswitch.org
https://mail.openvswitch.org/mailman/listinfo/ovs-dev


Re: [ovs-dev] [PATCH] Documentation: Fix DPDK qos example.

2021-02-18 Thread Eelco Chaudron




On 18 Feb 2021, at 15:40, William Tu wrote:

On Thu, Feb 18, 2021 at 1:23 AM Eelco Chaudron  
wrote:




On 17 Feb 2021, at 18:41, William Tu wrote:




 Information Rate). High priority traffic is routed to queue 10,
which marks
 all traffic as CIR, i.e. Green. All low priority traffic, queue 
20,

is
 marked as EIR, i.e. Yellow::

 $ ovs-vsctl --timeout=5 set port dpdk1 qos=@myqos -- \
 --id=@myqos create qos type=trtcm-policer \
-other-config:cir=52000 other-config:cbs=2048 \
-other-config:eir=52000 other-config:ebs=2048  \


52000 is fine as our documentation states cir, eir are in bytes per
second, minus the ethernet header.
So (64-12) * 1000 = 52000


How come it's not minus 14-byte ethernet header?


You are right, it should be 14, miscounted the rte_ether_hdr 
structure size :(



Thank you!
at vswitchd/vswitch.xml, it uses "46", should I change it to "64- 14 = 
50"?
calculated by (pps x packet data size).  For example assuming 
a user
wishes to limit a stream consisting of 64 byte packets to 1 
million
packets per second the EIR would be set to to to 4600. 
This value
can be broken into '1,000,000 x 46'. Where 1,000,000 is the 
policing
rate for the number of packets per second and 46 represents 
the size

of the packet data for a 64 byte ip packet.
William


Guess they take of the FCS also, so the packets they sent are 14 bytes 
ethernet, + 46 bytes IP + 4 FCS.


In my tests I sent 64 byte packets, i.e. 14 bytes ethernet + 50 bytes 
IP.


Maybe we should clarify this in the text some how?

___
dev mailing list
d...@openvswitch.org
https://mail.openvswitch.org/mailman/listinfo/ovs-dev


Re: [ovs-dev] [PATCH] Documentation: Fix DPDK qos example.

2021-02-18 Thread William Tu
On Thu, Feb 18, 2021 at 1:23 AM Eelco Chaudron  wrote:
>
>
>
> On 17 Feb 2021, at 18:41, William Tu wrote:
>
> >>
>   Information Rate). High priority traffic is routed to queue 10,
>  which marks
>   all traffic as CIR, i.e. Green. All low priority traffic, queue 20,
>  is
>   marked as EIR, i.e. Yellow::
> 
>   $ ovs-vsctl --timeout=5 set port dpdk1 qos=@myqos -- \
>   --id=@myqos create qos type=trtcm-policer \
>  -other-config:cir=52000 other-config:cbs=2048 \
>  -other-config:eir=52000 other-config:ebs=2048  \
> >>
> >> 52000 is fine as our documentation states cir, eir are in bytes per
> >> second, minus the ethernet header.
> >> So (64-12) * 1000 = 52000
> >
> > How come it's not minus 14-byte ethernet header?
>
> You are right, it should be 14, miscounted the rte_ether_hdr structure size :(
>
Thank you!
at vswitchd/vswitch.xml, it uses "46", should I change it to "64- 14 = 50"?
calculated by (pps x packet data size).  For example assuming a user
wishes to limit a stream consisting of 64 byte packets to 1 million
packets per second the EIR would be set to to to 4600. This value
can be broken into '1,000,000 x 46'. Where 1,000,000 is the policing
rate for the number of packets per second and 46 represents the size
of the packet data for a 64 byte ip packet.
William
___
dev mailing list
d...@openvswitch.org
https://mail.openvswitch.org/mailman/listinfo/ovs-dev


Re: [ovs-dev] [PATCH ovn] northd: Provide the Gateway router option 'lb_force_snat_ip' to take router port ips.

2021-02-18 Thread Numan Siddique
On Wed, Feb 17, 2021 at 7:37 PM Mark Gray  wrote:
>
> Thanks Numan, some suggestions below!

Hi Mark G,

Thanks for the review.

PSB for a few comments.

>
> On 09/02/2021 18:44, num...@ovn.org wrote:
> > From: Numan Siddique 
> >
> > When a Gateway router is configured with a load balancer
> > and it is also configured with options:lb_force_snat_ip=,
> > OVN after load balancing the destination IP to one of the
> > backend also does a NAT on the source ip with the
> > lb_force_snat_ip if the packet is destined to a load balancer
> > VIP.
> >
> > There is a problem with the snat of source ip to 'lb_force_snat_ip'
> > in one particular usecase.  When the packet enters the Gateway router
> > from a provider logical switch destined to the load balancer VIP,
> > then it is first load balanced to one of the backend and then
> > the source ip is snatted to 'lb_force_snat_ip'.  If the chosen
> > backend is reachable via the provider logical switch, then the
> > packet is hairpinned back and it may hit the wire with
> > the source ip 'lb_force_snat_ip'.  If 'lb_force_snat_ip' happens
> > to be an OVN internal IP then the packet may be dropped.
> >
> > This patch addresses this issue by providing the option to
> > set the option - 'lb_force_snat_ip=router_ip'.  If 'router_ip'
> > is set, then OVN will snat the load balanced packet to the
> > router ip of the logical router port which chosen as 'outport'
> > in lr_in_ip_routing stage.
>
> It almost feels like this should be the default behaviour?


Can you please elaborate more ? You mean ideally CMS should set
- router_ip ?


> >
> > Example.
> >
> > If the gateway router is
> >
> > ovn-nbctl show lr0
> > router 68f20092-5563-44b8-9ccb-b11de3e3a66c (lr0)
> > port lr0-sw0
> > mac: "00:00:00:00:ff:01"
> > networks: ["10.0.0.1/24"]
> > port lr0-public
> > mac: "00:00:20:20:12:13"
> > networks: ["172.168.0.100/24"]
> >
> > Then the below logical flows are added if 'lb_force_snat_ip'
> > is configured to 'router_ip'.
> >
> > table=1 (lr_out_snat), priority=110
> >match=(flags.force_snat_for_lb == 1 && ip4 && outport == "lr0-public"),
> >action=(ct_snat(172.168.0.100);)
> >
> > table=1 (lr_out_snat), priority=110
> >match=(flags.force_snat_for_lb == 1 && ip4 && outport == "lr0-sw0")
> >action=(ct_snat(10.0.0.1);)
> >
> > For the above described scenario, the packet will have source ip as
> > 172.168.0.100 which belongs to the provider logical switch CIDR.
> >
> > Reported-by: Tim Rozet 
> > Signed-off-by: Numan Siddique 
> > ---
> >  northd/ovn-northd.8.xml | 35 ++
> >  northd/ovn-northd.c | 66 --
> >  tests/ovn-northd.at | 79 +
> >  3 files changed, 177 insertions(+), 3 deletions(-)
> >
> > diff --git a/northd/ovn-northd.8.xml b/northd/ovn-northd.8.xml
> > index 70065a36d9..27b28aff93 100644
> > --- a/northd/ovn-northd.8.xml
> > +++ b/northd/ovn-northd.8.xml
>
> Should 'ovn-nb.xml' also be updated?

Great catch. I totally missed it.

>
> > @@ -3653,6 +3653,32 @@ nd_ns {
> >flags.force_snat_for_dnat == 1  ip with an
> >action ct_snat(B);.
> >  
> > +  
> > +
> > +  
> > +
> > +  If the Gateway router in the OVN Northbound database has been
> > +  configured to force SNAT a packet (that has been previously
> > +  load-balanced) using router IP (i.e  > +  table="Logical_Router"/>:lb_force_snat_ip=router_ip), then for
> > +  each logical router port P attached to the Gateway
> > +  router, a priority-110 flow matches
> > +  flags.force_snat_for_lb == 1  outport == 
> > P
> > +   with an action ct_snat(R);
> > +  where R is the router port IP configured.
>
> maybe rephrase to "is the IP configured on the router port."

Ack. done

>
> > +  If R is an IPv4 address then the match will also
> > +  include ip4 and if it is an IPv6 address, then the
> > +  match will also include ip6.
> > +
> > +
> > +
> > +  If the logical router port P is configured with 
> > multiple
> > +  IPv4 and multiple IPv6 addresses, only the first IPv4 and first 
> > IPv6
> > +  address is considered.
>
> Should we log this condition?

Ack. I have added the log for this in v2.


>
> > +
> > +  
> > +
> > +  
> >  
> >If the Gateway router in the OVN Northbound database has been
> >configured to force SNAT a packet (that has been previously
> > @@ -3660,6 +3686,9 @@ nd_ns {
> >flags.force_snat_for_lb == 1  ip with an
> >action ct_snat(B);.
> >  
> > +  
> > +
> > +  
> >  
> >For each configuration in the OVN Northbound database, that asks
> >to change the source IP address of a packet from an IP address of
> > @@ -3673,14 +3702,18 @@ nd_ns {
> >   

[ovs-dev] [PATCH ovn v2] northd: Provide the Gateway router option 'lb_force_snat_ip' to take router port ips.

2021-02-18 Thread numans
From: Numan Siddique 

When a Gateway router is configured with a load balancer
and it is also configured with options:lb_force_snat_ip=,
OVN after load balancing the destination IP to one of the
backend also does a NAT on the source ip with the
lb_force_snat_ip if the packet is destined to a load balancer
VIP.

There is a problem with the snat of source ip to 'lb_force_snat_ip'
in one particular usecase.  When the packet enters the Gateway router
from a provider logical switch destined to the load balancer VIP,
then it is first load balanced to one of the backend and then
the source ip is snatted to 'lb_force_snat_ip'.  If the chosen
backend is reachable via the provider logical switch, then the
packet is hairpinned back and it may hit the wire with
the source ip 'lb_force_snat_ip'.  If 'lb_force_snat_ip' happens
to be an OVN internal IP then the packet may be dropped.

This patch addresses this issue by providing the option to
set the option - 'lb_force_snat_ip=router_ip'.  If 'router_ip'
is set, then OVN will snat the load balanced packet to the
router ip of the logical router port which is chosen as 'outport'
in lr_in_ip_routing stage.

Example.

If the gateway router is

ovn-nbctl show lr0
router 68f20092-5563-44b8-9ccb-b11de3e3a66c (lr0)
port lr0-sw0
mac: "00:00:00:00:ff:01"
networks: ["10.0.0.1/24"]
port lr0-public
mac: "00:00:20:20:12:13"
networks: ["172.168.0.100/24"]

Then the below logical flows are added if 'lb_force_snat_ip'
is configured to 'router_ip'.

table=1 (lr_out_snat), priority=110
   match=(flags.force_snat_for_lb == 1 && ip4 && outport == "lr0-public"),
   action=(ct_snat(172.168.0.100);)

table=1 (lr_out_snat), priority=110
   match=(flags.force_snat_for_lb == 1 && ip4 && outport == "lr0-sw0")
   action=(ct_snat(10.0.0.1);)

For the above described scenario, the packet will have source ip as
172.168.0.100 which belongs to the provider logical switch CIDR.

Reported-by: Tim Rozet 
Signed-off-by: Numan Siddique 
---

v1 -> v2
---
  * Addressed review comments from Mark Gray.

 northd/ovn-northd.8.xml | 35 
 northd/ovn-northd.c | 93 +
 ovn-nb.xml  | 33 ++-
 tests/ovn-northd.at | 79 ++
 4 files changed, 222 insertions(+), 18 deletions(-)

diff --git a/northd/ovn-northd.8.xml b/northd/ovn-northd.8.xml
index 2f8b4e8c30..1d8f5edee1 100644
--- a/northd/ovn-northd.8.xml
+++ b/northd/ovn-northd.8.xml
@@ -3654,6 +3654,32 @@ nd_ns {
   flags.force_snat_for_dnat == 1  ip with an
   action ct_snat(B);.
 
+  
+
+  
+
+  If the Gateway router in the OVN Northbound database has been
+  configured to force SNAT a packet (that has been previously
+  load-balanced) using router IP (i.e :lb_force_snat_ip=router_ip), then for
+  each logical router port P attached to the Gateway
+  router, a priority-110 flow matches
+  flags.force_snat_for_lb == 1  outport == P
+   with an action ct_snat(R);
+  where R is the IP configured on the router port.
+  If R is an IPv4 address then the match will also
+  include ip4 and if it is an IPv6 address, then the
+  match will also include ip6.
+
+
+
+  If the logical router port P is configured with multiple
+  IPv4 and multiple IPv6 addresses, only the first IPv4 and first IPv6
+  address is considered.
+
+  
+
+  
 
   If the Gateway router in the OVN Northbound database has been
   configured to force SNAT a packet (that has been previously
@@ -3661,6 +3687,9 @@ nd_ns {
   flags.force_snat_for_lb == 1  ip with an
   action ct_snat(B);.
 
+  
+
+  
 
   For each configuration in the OVN Northbound database, that asks
   to change the source IP address of a packet from an IP address of
@@ -3674,14 +3703,18 @@ nd_ns {
   options, then the action would be ip4/6.src=
   (B).
 
+  
 
+  
 
   If the NAT rule has allowed_ext_ips configured, then
   there is an additional match ip4.dst == allowed_ext_ips
   . Similarly, for IPV6, match would be ip6.dst ==
   allowed_ext_ips.
 
+  
 
+  
 
   If the NAT rule has exempted_ext_ips set, then
   there is an additional flow configured at the priority + 1 of
@@ -3690,7 +3723,9 @@ nd_ns {
   . This flow is used to bypass the ct_snat action for a packet
   which is destinted to exempted_ext_ips.
 
+  
 
+  
 
   A priority-0 logical flow with match 1 has actions
   next;.
diff --git a/northd/ovn-northd.c b/northd/ovn-northd.c
index 39d7987820..816836ab02 100644
--- a/northd/ovn-northd.c
+++ b/northd/ovn-northd.c
@@ -624,6 +624,7 @@ struct 

Re: [ovs-dev] [PATCH] ci: Use parrallel build for distcheck.

2021-02-18 Thread Aaron Conole
Ilya Maximets  writes:

> 'distcheck' target builds the whole OVS, but for some reason we're
> running it in a single-threaded mode.  Running in parallel saves
> a couple of minutes.
>
> Signed-off-by: Ilya Maximets 
> ---

Cool - from what I can tell of the jobs, it shaves a couple minutes off
the build time (looking at the 'linux gcc test' builds that run the
distcheck).

Acked-by: Aaron Conole 

___
dev mailing list
d...@openvswitch.org
https://mail.openvswitch.org/mailman/listinfo/ovs-dev


Re: [ovs-dev] [PATCH V2 00/14] Netdev vxlan-decap offload

2021-02-18 Thread Pai G, Sunil
Sending to Marko. As he wasn't subscribed to ovs-dev then.

> -Original Message-
> From: dev  On Behalf Of Eli Britstein
> Sent: Wednesday, February 10, 2021 8:57 PM
> To: d...@openvswitch.org; Ilya Maximets 
> Cc: Eli Britstein ; Ameer Mahagneh
> ; Majd Dibbiny ; Gaetan Rivet
> 
> Subject: [ovs-dev] [PATCH V2 00/14] Netdev vxlan-decap offload
> 
> VXLAN decap in OVS-DPDK configuration consists of two flows:
> F1: in_port(ens1f0),eth(),ipv4(),udp(), actions:tnl_pop(vxlan_sys_4789)
> F2: tunnel(),in_port(vxlan_sys_4789),eth(),ipv4(), actions:ens1f0_0
> 
> F1 is a classification flow. It has outer headers matches and it classifies 
> the
> packet as a VXLAN packet, and using tnl_pop action the packet continues
> processing in F2.
> F2 is a flow that has matches on tunnel metadata as well as on the inner
> packet headers (as any other flow).
> 
> In order to fully offload VXLAN decap path, both F1 and F2 should be
> offloaded. As there are more than one flow in HW, it is possible that
> F1 is done by HW but F2 is not. Packet is received by SW, and should be
> processed starting from F2 as F1 was already done by HW.
> Rte_flows are applicable only on physical port IDs. Keeping the original
> physical in port on which the packet is received on enables applying vport
> flows (e.g. F2) on that physical port.
> 
> This patch-set makes use of [1] introduced in DPDK 20.11, that adds API for
> tunnel offloads.
> 
> v2-v1:
> - Tracking original in_port, and applying vport on that physical port instead 
> of
> all PFs.
> 
> Travis:
> v1: https://travis-ci.org/github/elibritstein/OVS/builds/756418552
> v2: https://travis-ci.org/github/elibritstein/OVS/builds/758382963
> 
> GitHub Actions:
> v1: https://github.com/elibritstein/OVS/actions/runs/515334647
> v2: https://github.com/elibritstein/OVS/actions/runs/554986007
> 
> [1] https://mails.dpdk.org/archives/dev/2020-October/187314.html
> 
> Eli Britstein (11):
>   netdev-offload: Add HW miss packet state recover API
>   netdev-dpdk: Introduce DPDK tunnel APIs
>   netdev-offload-dpdk: Implement flow dump create/destroy APIs
>   netdev-dpdk: Add flow_api support for netdev vxlan vports
>   netdev-offload-dpdk: Implement HW miss packet recover for vport
>   dpif-netdev: Add HW miss packet state recover logic
>   netdev-offload-dpdk: Change log rate limits
>   netdev-offload-dpdk: Support tunnel pop action
>   netdev-offload-dpdk: Refactor offload rule creation
>   netdev-offload-dpdk: Support vports flows offload
>   netdev-dpdk-offload: Add vxlan pattern matching function
> 
> Ilya Maximets (2):
>   netdev-offload: Allow offloading to netdev without ifindex.
>   netdev-offload: Disallow offloading to unrelated tunneling vports.
> 
> Sriharsha Basavapatna (1):
>   dpif-netdev: Provide orig_in_port in metadata for tunneled packets
> 
>  Documentation/howto/dpdk.rst  |   1 +
>  NEWS  |   2 +
>  lib/dpif-netdev.c |  69 ++--
>  lib/netdev-dpdk.c | 118 ++
>  lib/netdev-dpdk.h | 102 -
>  lib/netdev-offload-dpdk.c | 706 +-
>  lib/netdev-offload-provider.h |   5 +
>  lib/netdev-offload-tc.c   |   8 +
>  lib/netdev-offload.c  |  29 +-
>  lib/netdev-offload.h  |   2 +
>  lib/packets.h |   8 +-
>  11 files changed, 921 insertions(+), 129 deletions(-)
> 
> --
> 2.28.0.546.g385c171
> 
> ___
> dev mailing list
> d...@openvswitch.org
> https://mail.openvswitch.org/mailman/listinfo/ovs-dev
___
dev mailing list
d...@openvswitch.org
https://mail.openvswitch.org/mailman/listinfo/ovs-dev


Re: [ovs-dev] [PATCH v2 ovn] controller: introduce coverage_counters for ovn-controller incremental processing

2021-02-18 Thread Lorenzo Bianconi
> On 17/02/2021 19:33, Lorenzo Bianconi wrote:
> 
> Should the subject have an underscore? 'coverage_counters'

ops, sorry..I forgot to fix it.

> 
> > In order to help understanding system behaviour for debugging purpose,
> > introduce coverage counters for run handlers of ovn-controller
> > I-P engine nodes. Moreover add a global counter for engine abort.
> > 
> > https://bugzilla.redhat.com/show_bug.cgi?id=1890902
> > Signed-off-by: Lorenzo Bianconi 
> > ---
> > Changes since v1:
> > - drop handler counters and add global abort counter
> > - improve documentation and naming scheme
> > - introduce engine_set_node_updated utility macro
> > ---
> >  controller/ovn-controller.c | 39 +++--
> >  lib/inc-proc-eng.c  |  5 +
> >  lib/inc-proc-eng.h  | 12 +++-
> >  3 files changed, 45 insertions(+), 11 deletions(-)
> > 
> > diff --git a/controller/ovn-controller.c b/controller/ovn-controller.c
> > index 4343650fc..42eed9ebd 100644
> > --- a/controller/ovn-controller.c
> > +++ b/controller/ovn-controller.c
> > @@ -69,6 +69,7 @@
> >  #include "stopwatch.h"
> >  #include "lib/inc-proc-eng.h"
> >  #include "hmapx.h"
> > +#include "coverage.h"
> >  
> >  VLOG_DEFINE_THIS_MODULE(main);
> >  
> > @@ -85,6 +86,18 @@ static unixctl_cb_func lflow_cache_flush_cmd;
> >  static unixctl_cb_func lflow_cache_show_stats_cmd;
> >  static unixctl_cb_func debug_delay_nb_cfg_report;
> >  
> > +/* Coverage counters for run handlers of OVN controller
> > + * incremental processing nodes
> > + */
> > +ENGINE_RUN_COVERAGE_DEFINE(flow_output);
> > +ENGINE_RUN_COVERAGE_DEFINE(runtime_data);
> > +ENGINE_RUN_COVERAGE_DEFINE(addr_sets);
> > +ENGINE_RUN_COVERAGE_DEFINE(port_groups);
> > +ENGINE_RUN_COVERAGE_DEFINE(ct_zones);
> > +ENGINE_RUN_COVERAGE_DEFINE(mff_ovn_geneve);
> > +ENGINE_RUN_COVERAGE_DEFINE(ofctrl_is_connected);
> > +ENGINE_RUN_COVERAGE_DEFINE(physical_flow_changes);
> 
> 
> I would like these counters to be part of the framework (i.e.
> inc-proc-eng.c/h) rather than being exposed out. The reasoning is that
> we shouldn't rely on a developer to modify them correctly when updating
> the _handler() and the _run() functions as it is too error-prone IMHO.
> For example, if a _run() function exits early and also sets a node to
> updated or aborts a node, will the developer/reviewer remember to update
> the corresponding counter? Also, if we need to make changes to the
> counters, it would be preferable to make the changes in one location.
> 
> I realize that this causes issues for per-node counters as currently
> implemented: inc-proc-eng.c has no idea about which nodes are which at
> compilation time and COVERAGE_INC() is a macro which requires templating
> the name of the node at compilation time.
> 
> For this reason, I suggest the following:
> 
> * Add counters to 'struct engine_node' and/or 'struct engine_context'
> * Create an ovs-appctl command, something like `ovs-appctl-ctl -t
> ovs-controller inc-proc-eng/stats-show` and `ovs-appctl-ctl -t
> ovs-controller inc-proc-eng/stats-clear` that will show/clear these
> stats to the user
> 
> This follows a common pattern in OVS/OVN code. e.g.
> https://github.com/openvswitch/ovs/blob/master/Documentation/topics/dpdk/pmd.rst#pmd-thread-statistics.
> 
> The next question is what counters to expose. As I think it should be
> easier to expose counters using the `appctl` above, I would suggest
> exposing as much as you can. However, you could also get feedback from
> those in the community who have more operational experience with OVN.
> 
> Here are some suggestions:
> 
> * Total number of engine runs
> * Total number of engine aborts
> * Total number of engine recomputes
> * Number of runs for each node
> * Number of computes for each node
> * Number of recomputes for each node
> * Number of transitions to ABORT for each node
> * Number of transitions to UNCHANGED for each node
> * Number of transitions to UPDATED for each node
> 
> What do you think?

yes, I like the idea...avoiding COVERAGE_* macros will allow a more manageable
code. I will work on a PoC, thx :)

Regards,
Lorenzo

> 
> > +
> >  #define DEFAULT_BRIDGE_NAME "br-int"
> >  #define DEFAULT_PROBE_INTERVAL_MSEC 5000
> >  #define OFCTRL_DEFAULT_PROBE_INTERVAL_SEC 0
> > @@ -955,6 +968,10 @@ ctrl_register_ovs_idl(struct ovsdb_idl *ovs_idl)
> >  SB_NODE(dns, "dns") \
> >  SB_NODE(load_balancer, "load_balancer")
> >  
> > +#define SB_NODE(NAME, NAME_STR) ENGINE_RUN_COVERAGE_DEFINE(sb_##NAME);
> > +SB_NODES
> > +#undef SB_NODE
> > +
> >  enum sb_engine_node {
> >  #define SB_NODE(NAME, NAME_STR) SB_##NAME,
> >  SB_NODES
> > @@ -972,6 +989,10 @@ enum sb_engine_node {
> >  OVS_NODE(interface, "interface") \
> >  OVS_NODE(qos, "qos")
> >  
> > +#define OVS_NODE(NAME, NAME_STR) ENGINE_RUN_COVERAGE_DEFINE(ovs_##NAME);
> > +OVS_NODES
> > +#undef OVS_NODE
> > +
> >  enum ovs_engine_node {
> >  #define OVS_NODE(NAME, NAME_STR) OVS_##NAME,
> >  

Re: [ovs-dev] [PATCH] ci: Use parrallel build for distcheck.

2021-02-18 Thread Ilya Maximets
On 2/18/21 1:20 PM, Tonghao Zhang wrote:
> On Thu, Feb 18, 2021 at 6:33 PM Ilya Maximets  wrote:
>>
>> 'distcheck' target builds the whole OVS, but for some reason we're
>> running it in a single-threaded mode.  Running in parallel saves
>> a couple of minutes.
>>
>> Signed-off-by: Ilya Maximets 
>> ---
>>  .ci/linux-build.sh | 2 +-
>>  1 file changed, 1 insertion(+), 1 deletion(-)
>>
>> diff --git a/.ci/linux-build.sh b/.ci/linux-build.sh
>> index 581ab..977449350 100755
>> --- a/.ci/linux-build.sh
>> +++ b/.ci/linux-build.sh
>> @@ -244,7 +244,7 @@ if [ "$TESTSUITE" ]; then
>>  configure_ovs
>>
>>  export DISTCHECK_CONFIGURE_FLAGS="$OPTS"
>> -if ! make distcheck CFLAGS="${CFLAGS_FOR_OVS}" \
>> +if ! make distcheck -j4 CFLAGS="${CFLAGS_FOR_OVS}" \
> why not use $(nproc)?
>>   TESTSUITEFLAGS=-j4 RECHECK=yes; then
> and -j4 -->  $(nproc) ?

CI systems provides 2 CPUs, so nproc is equal to 2.
Both build and tests are IO intensive and not able to fully utilize
CPU resources while waiting on IO, so we're creating more threads
than CPUs.  From my experience 2x is enough, higher parallelism
doesn't usually give any improvement.

We can replace 4 with 'nproc * 2', but I do not expect changes in
number of available CPU cores in CI, so it's not very important.


>>  # testsuite.log is necessary for debugging.
>>  cat */_build/sub/tests/testsuite.log
>> --
>> 2.26.2
___
dev mailing list
d...@openvswitch.org
https://mail.openvswitch.org/mailman/listinfo/ovs-dev


Re: [ovs-dev] [PATCH] ci: Use parrallel build for distcheck.

2021-02-18 Thread Tonghao Zhang
On Thu, Feb 18, 2021 at 6:33 PM Ilya Maximets  wrote:
>
> 'distcheck' target builds the whole OVS, but for some reason we're
> running it in a single-threaded mode.  Running in parallel saves
> a couple of minutes.
>
> Signed-off-by: Ilya Maximets 
> ---
>  .ci/linux-build.sh | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/.ci/linux-build.sh b/.ci/linux-build.sh
> index 581ab..977449350 100755
> --- a/.ci/linux-build.sh
> +++ b/.ci/linux-build.sh
> @@ -244,7 +244,7 @@ if [ "$TESTSUITE" ]; then
>  configure_ovs
>
>  export DISTCHECK_CONFIGURE_FLAGS="$OPTS"
> -if ! make distcheck CFLAGS="${CFLAGS_FOR_OVS}" \
> +if ! make distcheck -j4 CFLAGS="${CFLAGS_FOR_OVS}" \
why not use $(nproc)?
>   TESTSUITEFLAGS=-j4 RECHECK=yes; then
and -j4 -->  $(nproc) ?
>  # testsuite.log is necessary for debugging.
>  cat */_build/sub/tests/testsuite.log
> --
> 2.26.2
>
> ___
> dev mailing list
> d...@openvswitch.org
> https://mail.openvswitch.org/mailman/listinfo/ovs-dev



-- 
Best regards, Tonghao
___
dev mailing list
d...@openvswitch.org
https://mail.openvswitch.org/mailman/listinfo/ovs-dev


Re: [ovs-dev] [PATCH v2 ovn] controller: introduce coverage_counters for ovn-controller incremental processing

2021-02-18 Thread Mark Gray
On 17/02/2021 19:33, Lorenzo Bianconi wrote:

Should the subject have an underscore? 'coverage_counters'

> In order to help understanding system behaviour for debugging purpose,
> introduce coverage counters for run handlers of ovn-controller
> I-P engine nodes. Moreover add a global counter for engine abort.
> 
> https://bugzilla.redhat.com/show_bug.cgi?id=1890902
> Signed-off-by: Lorenzo Bianconi 
> ---
> Changes since v1:
> - drop handler counters and add global abort counter
> - improve documentation and naming scheme
> - introduce engine_set_node_updated utility macro
> ---
>  controller/ovn-controller.c | 39 +++--
>  lib/inc-proc-eng.c  |  5 +
>  lib/inc-proc-eng.h  | 12 +++-
>  3 files changed, 45 insertions(+), 11 deletions(-)
> 
> diff --git a/controller/ovn-controller.c b/controller/ovn-controller.c
> index 4343650fc..42eed9ebd 100644
> --- a/controller/ovn-controller.c
> +++ b/controller/ovn-controller.c
> @@ -69,6 +69,7 @@
>  #include "stopwatch.h"
>  #include "lib/inc-proc-eng.h"
>  #include "hmapx.h"
> +#include "coverage.h"
>  
>  VLOG_DEFINE_THIS_MODULE(main);
>  
> @@ -85,6 +86,18 @@ static unixctl_cb_func lflow_cache_flush_cmd;
>  static unixctl_cb_func lflow_cache_show_stats_cmd;
>  static unixctl_cb_func debug_delay_nb_cfg_report;
>  
> +/* Coverage counters for run handlers of OVN controller
> + * incremental processing nodes
> + */
> +ENGINE_RUN_COVERAGE_DEFINE(flow_output);
> +ENGINE_RUN_COVERAGE_DEFINE(runtime_data);
> +ENGINE_RUN_COVERAGE_DEFINE(addr_sets);
> +ENGINE_RUN_COVERAGE_DEFINE(port_groups);
> +ENGINE_RUN_COVERAGE_DEFINE(ct_zones);
> +ENGINE_RUN_COVERAGE_DEFINE(mff_ovn_geneve);
> +ENGINE_RUN_COVERAGE_DEFINE(ofctrl_is_connected);
> +ENGINE_RUN_COVERAGE_DEFINE(physical_flow_changes);


I would like these counters to be part of the framework (i.e.
inc-proc-eng.c/h) rather than being exposed out. The reasoning is that
we shouldn't rely on a developer to modify them correctly when updating
the _handler() and the _run() functions as it is too error-prone IMHO.
For example, if a _run() function exits early and also sets a node to
updated or aborts a node, will the developer/reviewer remember to update
the corresponding counter? Also, if we need to make changes to the
counters, it would be preferable to make the changes in one location.

I realize that this causes issues for per-node counters as currently
implemented: inc-proc-eng.c has no idea about which nodes are which at
compilation time and COVERAGE_INC() is a macro which requires templating
the name of the node at compilation time.

For this reason, I suggest the following:

* Add counters to 'struct engine_node' and/or 'struct engine_context'
* Create an ovs-appctl command, something like `ovs-appctl-ctl -t
ovs-controller inc-proc-eng/stats-show` and `ovs-appctl-ctl -t
ovs-controller inc-proc-eng/stats-clear` that will show/clear these
stats to the user

This follows a common pattern in OVS/OVN code. e.g.
https://github.com/openvswitch/ovs/blob/master/Documentation/topics/dpdk/pmd.rst#pmd-thread-statistics.

The next question is what counters to expose. As I think it should be
easier to expose counters using the `appctl` above, I would suggest
exposing as much as you can. However, you could also get feedback from
those in the community who have more operational experience with OVN.

Here are some suggestions:

* Total number of engine runs
* Total number of engine aborts
* Total number of engine recomputes
* Number of runs for each node
* Number of computes for each node
* Number of recomputes for each node
* Number of transitions to ABORT for each node
* Number of transitions to UNCHANGED for each node
* Number of transitions to UPDATED for each node

What do you think?

> +
>  #define DEFAULT_BRIDGE_NAME "br-int"
>  #define DEFAULT_PROBE_INTERVAL_MSEC 5000
>  #define OFCTRL_DEFAULT_PROBE_INTERVAL_SEC 0
> @@ -955,6 +968,10 @@ ctrl_register_ovs_idl(struct ovsdb_idl *ovs_idl)
>  SB_NODE(dns, "dns") \
>  SB_NODE(load_balancer, "load_balancer")
>  
> +#define SB_NODE(NAME, NAME_STR) ENGINE_RUN_COVERAGE_DEFINE(sb_##NAME);
> +SB_NODES
> +#undef SB_NODE
> +
>  enum sb_engine_node {
>  #define SB_NODE(NAME, NAME_STR) SB_##NAME,
>  SB_NODES
> @@ -972,6 +989,10 @@ enum sb_engine_node {
>  OVS_NODE(interface, "interface") \
>  OVS_NODE(qos, "qos")
>  
> +#define OVS_NODE(NAME, NAME_STR) ENGINE_RUN_COVERAGE_DEFINE(ovs_##NAME);
> +OVS_NODES
> +#undef OVS_NODE
> +
>  enum ovs_engine_node {
>  #define OVS_NODE(NAME, NAME_STR) OVS_##NAME,
>  OVS_NODES
> @@ -1011,7 +1032,7 @@ en_ofctrl_is_connected_run(struct engine_node *node, 
> void *data)
>  ofctrl_seqno_flush();
>  binding_seqno_flush();
>  }
> -engine_set_node_state(node, EN_UPDATED);
> +engine_set_node_updated(node, ofctrl_is_connected);
>  return;
>  }
>  engine_set_node_state(node, EN_UNCHANGED);
> @@ -1067,7 +1088,7 @@ 

[ovs-dev] [PATCH 0/1] PMD auto balance unit tests.

2021-02-18 Thread Kevin Traynor
These are some initial unit tests for PMD auto load balance that focus
on enabling/disabling and user parameters.

While writing these, I found some gaps in the logs and sent patches [1].
The existing logs were not incorrect but there was a few scenarios where
it would be reasonable and helpful to expect a log that didn't appear.

v1:
- Patch 1/2 in [1] that logs the state of alb was applied
- Patch 2/2 in [1] that logs the reason alb was not enabled was not applied
- Make v1 and remove check for reason logs

[1] http://patchwork.ozlabs.org/project/openvswitch/list/?series=228233

Kevin Traynor (1):
  tests: Add PMD auto load balance unit tests.

 tests/alb.at   | 256 +
 tests/automake.mk  |   1 +
 tests/testsuite.at |   1 +
 3 files changed, 258 insertions(+)
 create mode 100644 tests/alb.at

-- 
2.26.2

___
dev mailing list
d...@openvswitch.org
https://mail.openvswitch.org/mailman/listinfo/ovs-dev


[ovs-dev] [PATCH 1/1] tests: Add PMD auto load balance unit tests.

2021-02-18 Thread Kevin Traynor
These tests focus on enabling/disabling and user parameters.

Signed-off-by: Kevin Traynor 
---
 tests/alb.at   | 256 +
 tests/automake.mk  |   1 +
 tests/testsuite.at |   1 +
 3 files changed, 258 insertions(+)
 create mode 100644 tests/alb.at

diff --git a/tests/alb.at b/tests/alb.at
new file mode 100644
index 0..136c26c44
--- /dev/null
+++ b/tests/alb.at
@@ -0,0 +1,256 @@
+AT_BANNER([PMD Auto Load Balance])
+
+m4_divert_push([PREPARE_TESTS])
+
+get_log_line_num () {
+LINENUM=$(cat ovs-vswitchd.log | wc -l | tr -d [[:blank:]])
+}
+
+m4_divert_pop([PREPARE_TESTS])
+
+m4_define([DUMMY_NUMA], [--dummy-numa="0,0"])
+
+dnl CHECK_INTERVAL_PARAM([interval_time],  [+line])
+dnl
+dnl Waits for alb interval time in logs and checks if time matches
+dnl $1. Checking starts from line number 'line' in ovs-vswithd.log .
+m4_define([CHECK_INTERVAL_PARAM], [
+PATTERN="PMD auto load balance interval set to [[0-9]]* mins"
+line_st=$2
+if [[ -z "$line_st" ]]
+then
+line_st="+0"
+fi
+OVS_WAIT_UNTIL([tail -n $line_st ovs-vswitchd.log | grep "$PATTERN"])
+TIME=$(tail -n $line_st ovs-vswitchd.log | grep "$PATTERN" | tail -1 | sed 
-e 's/.* \([[0-9]]*\) mins/\1/')
+AT_CHECK([test "$TIME" -eq "$1"])
+])
+
+dnl CHECK_LOAD_PARAM([load],  [+line])
+dnl
+dnl Waits for alb load threshold in logs and checks if threshold matches
+dnl $1. Checking starts from line number 'line' in ovs-vswithd.log .
+m4_define([CHECK_LOAD_PARAM], [
+PATTERN="PMD auto load balance load threshold set to [[0-9]]*"
+line_st=$2
+if [[ -z "$line_st" ]]
+then
+line_st="+0"
+fi
+OVS_WAIT_UNTIL([tail -n $line_st ovs-vswitchd.log | grep "$PATTERN"])
+LOAD=$(tail -n $line_st ovs-vswitchd.log | grep "$PATTERN" | tail -1 | tr 
-d '%' | sed -e 's/.* \([[0-9]]*\)/\1/')
+AT_CHECK([test "$LOAD" -eq "$1"])
+])
+
+dnl CHECK_IMPROVE_PARAM([load],  [+line])
+dnl
+dnl Waits for alb improve threshold in logs and checks if threshold matches
+dnl $1. Checking starts from line number 'line' in ovs-vswithd.log .
+m4_define([CHECK_IMPROVE_PARAM], [
+PATTERN="PMD auto load balance improvement threshold set to [[0-9]]*"
+line_st=$3
+if [[ -z "$line_st" ]]
+then
+line_st="+0"
+fi
+OVS_WAIT_UNTIL([tail -n $line_st ovs-vswitchd.log | grep "$PATTERN"])
+IMPROVE=$(tail -n $line_st ovs-vswitchd.log | grep "$PATTERN" | tail -1 | 
tr -d '%' | sed -e 's/.* \([[0-9]]*\)/\1/')
+AT_CHECK([test "$IMPROVE" -eq "$1"])
+])
+
+
+AT_SETUP([ALB - default state])
+OVS_VSWITCHD_START
+OVS_WAIT_UNTIL([grep "PMD auto load balance is disabled" ovs-vswitchd.log])
+
+OVS_VSWITCHD_STOP
+AT_CLEANUP
+
+AT_SETUP([ALB - enable/disable])
+OVS_VSWITCHD_START([add-port br0 p0 \
+-- set Interface p0 type=dummy-pmd options:n_rxq=3 \
+-- set Open_vSwitch . other_config:pmd-cpu-mask=3 \
+-- set open_vswitch . other_config:pmd-auto-lb="true"],
+   [], [], [DUMMY_NUMA])
+OVS_WAIT_UNTIL([grep "PMD auto load balance is enabled" ovs-vswitchd.log])
+
+get_log_line_num
+AT_CHECK([ovs-vsctl set open_vswitch . other_config:pmd-auto-lb="false"])
+OVS_WAIT_UNTIL([tail -n +$LINENUM ovs-vswitchd.log | grep "PMD auto load 
balance is disabled"])
+
+get_log_line_num
+AT_CHECK([ovs-vsctl set open_vswitch . other_config:pmd-auto-lb="true"])
+OVS_WAIT_UNTIL([tail -n +$LINENUM ovs-vswitchd.log | grep "PMD auto load 
balance is enabled"])
+
+OVS_VSWITCHD_STOP
+AT_CLEANUP
+
+AT_SETUP([ALB - min num PMD/RxQ])
+OVS_VSWITCHD_START([add-port br0 p0 \
+-- set Interface p0 type=dummy-pmd options:n_rxq=2 \
+-- set Open_vSwitch . other_config:pmd-cpu-mask=1 \
+-- set open_vswitch . other_config:pmd-auto-lb="true"],
+   [], [], [DUMMY_NUMA])
+OVS_WAIT_UNTIL([grep "PMD auto load balance is disabled" ovs-vswitchd.log])
+
+# Add more PMD
+AT_CHECK([ovs-vsctl set Open_vSwitch . other_config:pmd-cpu-mask=0x3])
+OVS_WAIT_UNTIL([grep "There are 2 pmd threads on numa node" ovs-vswitchd.log])
+
+# Add one more rxq to have 2 rxq on a PMD
+get_log_line_num
+AT_CHECK([ovs-vsctl set interface p0 options:n_rxq=3])
+OVS_WAIT_UNTIL([tail -n +$LINENUM ovs-vswitchd.log | grep "PMD auto load 
balance is enabled"])
+
+# Reduce PMD
+get_log_line_num
+AT_CHECK([ovs-vsctl set Open_vSwitch . other_config:pmd-cpu-mask=0x1])
+OVS_WAIT_UNTIL([tail -n +$LINENUM ovs-vswitchd.log | grep "PMD auto load 
balance is disabled"])
+
+# Check logs when try to enable but min PMD/RxQ prevents
+get_log_line_num
+AT_CHECK([ovs-vsctl set open_vswitch . other_config:pmd-auto-lb="false"])
+OVS_WAIT_UNTIL([tail -n +$LINENUM ovs-vswitchd.log | grep "PMD auto load 
balance is disabled"])
+get_log_line_num
+AT_CHECK([ovs-vsctl set open_vswitch . other_config:pmd-auto-lb="true"])
+OVS_WAIT_UNTIL([tail -n +$LINENUM ovs-vswitchd.log | grep "PMD auto load 
balance is 

[ovs-dev] [PATCH] ci: Use parrallel build for distcheck.

2021-02-18 Thread Ilya Maximets
'distcheck' target builds the whole OVS, but for some reason we're
running it in a single-threaded mode.  Running in parallel saves
a couple of minutes.

Signed-off-by: Ilya Maximets 
---
 .ci/linux-build.sh | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/.ci/linux-build.sh b/.ci/linux-build.sh
index 581ab..977449350 100755
--- a/.ci/linux-build.sh
+++ b/.ci/linux-build.sh
@@ -244,7 +244,7 @@ if [ "$TESTSUITE" ]; then
 configure_ovs
 
 export DISTCHECK_CONFIGURE_FLAGS="$OPTS"
-if ! make distcheck CFLAGS="${CFLAGS_FOR_OVS}" \
+if ! make distcheck -j4 CFLAGS="${CFLAGS_FOR_OVS}" \
  TESTSUITEFLAGS=-j4 RECHECK=yes; then
 # testsuite.log is necessary for debugging.
 cat */_build/sub/tests/testsuite.log
-- 
2.26.2

___
dev mailing list
d...@openvswitch.org
https://mail.openvswitch.org/mailman/listinfo/ovs-dev


Re: [ovs-dev] [PATCH v2] ofproto-dpif-xlate: fix zone set from non-frozen-metadata fields

2021-02-18 Thread 0-day Robot
Bleep bloop.  Greetings 贺鹏, I am a robot and I have tried out your patch.
Thanks for your contribution.

I encountered some error that I wasn't expecting.  See the details below.


checkpatch:
ERROR: Author Peng He  needs to sign off.
WARNING: Unexpected sign-offs from developers who are not authors or co-authors 
or committers: Peng He 
Lines checked: 163, Warnings: 1, Errors: 1


Please check this out.  If you feel there has been an error, please email 
acon...@redhat.com

Thanks,
0-day Robot
___
dev mailing list
d...@openvswitch.org
https://mail.openvswitch.org/mailman/listinfo/ovs-dev


Re: [ovs-dev] [PATCH v1] ofproto-dpif-xlate: fix zone set from non frozen metadata field

2021-02-18 Thread 贺鹏
Hi, I've already sent a v2 patch.

Mark Gray  于2021年2月17日周三 下午6:44写道:
>
> On 17/02/2021 10:40, 贺鹏 wrote:
> > Hi,
> >
> > Thanks for the review.
> >
> > Mark Gray  于2021年2月17日周三 下午6:13写道:
> >>
> >> I'm not too familiar with this code but I have some comments.
> >>
> >> On 15/02/2021 09:50, Peng He wrote:
> >>> CT zone could be set from a field that is not included in frozen
> >>> metedata. Consider the belowing cases which is normally used in
> >>
> >> Nits:
> >>
> >> s/metedata/metadata
> >> s/belowing cases which is/cases below which are
> >
> > sorry for the typo, will fix it in the next version
> >
> >>
> >>> OpenStack security group rules:
> >>>
> >>> priority=100,in_port=1,tcp,ct_state=-trk,action=ct(zone=5,table=0)
> >>> priority=100,in_port=1,tcp,ct_state=+trk,action=ct(commit,zone=NXM_NX_CT_ZONE[]),2
> >>>
> >>> The zone is set from the first rule's ct action. These two rules will
> >>> generate two megaflows: the first one uses zone=5 to query the CT module,
> >>> the second one set zone from the first megaflow and commit to CT.
> >>>
> >>> The current implementation will generate a megaflow which does not use
> >>> ct_zone=5 as a match, but directly commit into the ct using zone=5, as 
> >>> zone is
> >>> set by an Imm not a field.
> >>>
> >>> Consider a situation that one changes the zone id (for example to 15)
> >>> in the first rule however still keep the second rule unchanged. During
> >>> this change, there is traffic hitting the two generated megaflows, the
> >>> revaldiator would revalidate all megaflows, however, the revalidator will
> >>> not change the second megaflow, because zone=5 is recorded in the
> >>> megaflow, so the xlate will still translate the commit action into zone=5,
> >>> and the new traffic will still commit to CT as zone=5, not zone=15,
> >>> resulting in taffic drops and other issues.
> >>>
> >>> Just like OVS set-field action, if the field X is set by Y, we should also
> >>> mask Y as a match in the generated megaflow. An exception is that, if the 
> >>> zone
> >>> is set by the field that is included in the frozen state and this upcall 
> >>> is
> >>> a resume of a thawed xlate, the masking can be skipped, as if one changes
> >>> the previous rule, the generated recirc_id will be changed, and all 
> >>> megaflows
> >>> with the old recirc id will be invalid later, i.e. the revalidator will
> >>> not reuse the old megaflows at all.
> >>>
> >>> Fixes: 07659514c3 ("Add support for connection tracking.")
> >>> Reported-by: Sai Su 
> >>> Signed-off-by: Peng He 
> >>> ---
> >>>  include/openvswitch/meta-flow.h |  1 +
> >>>  lib/meta-flow.c | 13 +++
> >>>  ofproto/ofproto-dpif-xlate.c| 15 +
> >>>  tests/system-traffic.at | 39 +
> >>>  4 files changed, 68 insertions(+)
> >>>
> >>> diff --git a/include/openvswitch/meta-flow.h 
> >>> b/include/openvswitch/meta-flow.h
> >>> index 95e52e358..045dce8f5 100644
> >>> --- a/include/openvswitch/meta-flow.h
> >>> +++ b/include/openvswitch/meta-flow.h
> >>> @@ -2305,6 +2305,7 @@ void mf_set_flow_value_masked(const struct mf_field 
> >>> *,
> >>>const union mf_value *mask,
> >>>struct flow *);
> >>>  bool mf_is_tun_metadata(const struct mf_field *);
> >>> +bool mf_is_frozen_metadata(const struct mf_field *);
> >>>  bool mf_is_pipeline_field(const struct mf_field *);
> >>>  bool mf_is_set(const struct mf_field *, const struct flow *);
> >>>  void mf_mask_field(const struct mf_field *, struct flow_wildcards *);
> >>> diff --git a/lib/meta-flow.c b/lib/meta-flow.c
> >>> index c808d205d..e03cd8d0c 100644
> >>> --- a/lib/meta-flow.c
> >>> +++ b/lib/meta-flow.c
> >>> @@ -1788,6 +1788,19 @@ mf_is_tun_metadata(const struct mf_field *mf)
> >>> mf->id < MFF_TUN_METADATA0 + TUN_METADATA_NUM_OPTS;
> >>>  }
> >>>
> >>> +bool
> >>> +mf_is_frozen_metadata(const struct mf_field *mf)
> >>> +{
> >>> +if (mf->id >= MFF_TUN_ID && mf->id <= MFF_IN_PORT_OXM) {
> >>> +return true;
> >>> +}
> >>> +
> >>> +if (mf->id >= MFF_REG0 && mf->id < MFF_ETH_SRC) {
> >>> +return true;
> >>> +}
> >>> +return false;
> >>> +}
> >>> +
> >>>  bool
> >>>  mf_is_pipeline_field(const struct mf_field *mf)
> >>>  {
> >>> diff --git a/ofproto/ofproto-dpif-xlate.c b/ofproto/ofproto-dpif-xlate.c
> >>> index 7108c8a30..5d1f029fd 100644
> >>> --- a/ofproto/ofproto-dpif-xlate.c
> >>> +++ b/ofproto/ofproto-dpif-xlate.c
> >>> @@ -6212,6 +6212,21 @@ compose_conntrack_action(struct xlate_ctx *ctx, 
> >>> struct ofpact_conntrack *ofc,
> >>> >xin->flow, ctx->wc, zone);
> >>>  }
> >>>  }
> >>> +
> >>> +if (ofc->zone_src.field) {
> >>> +if (ctx->xin->frozen_state) {
> >>> +/* If the upcall is a resume of a recirculation, we only 
> >>> need to
> >>> + * unwildcard the fields that are not in the 
> >>> frozen_metadata, as
> >>> +  

[ovs-dev] [PATCH v2] ofproto-dpif-xlate: fix zone set from non-frozen-metadata fields

2021-02-18 Thread Peng He
CT zone could be set from a field that is not included in frozen
metadata. Consider the example rules which are typically seen in
OpenStack security group rules:

priority=100,in_port=1,tcp,ct_state=-trk,action=ct(zone=5,table=0)
priority=100,in_port=1,tcp,ct_state=+trk,action=ct(commit,zone=NXM_NX_CT_ZONE[]),2

The zone is set from the first rule's ct action. These two rules will
generate two megaflows: the first one uses zone=5 to query the CT module,
the second one sets the zone-id from the first megaflow and commit to CT.

The current implementation will generate a megaflow that does not use
ct_zone=5 as a match, but directly commit into the ct using zone=5, as zone is
set by an Imm not a field.

Consider a situation that one changes the zone id (for example to 15)
in the first rule, however, still keep the second rule unchanged. During
this change, there is traffic hitting the two generated megaflows, the
revaldiator would revalidate all megaflows, however, the revalidator will
not change the second megaflow, because zone=5 is recorded in the
megaflow, so the xlate will still translate the commit action into zone=5,
and the new traffic will still commit to CT as zone=5, not zone=15,
resulting in taffic drops and other issues.

Just like OVS set-field convention, if a field X is set by Y
(Y is a variable not an Imm), we should also mask Y as a match
in the generated megaflow. An exception is that if the zone-id is
set by the field that is included in the frozen state (i.e. regs) and this
upcall is a resume of a thawed xlate, the un-wildcarding can be skipped,
as the recirc_id is a hash of the values in these fields, and it will change
following the changes of these fields. When the recirc_id changes,
all megaflows with the old recirc id will be invalid later.

Fixes: 07659514c3 ("Add support for connection tracking.")
Reported-by: Sai Su 
Signed-off-by: Peng He 
---
 include/openvswitch/meta-flow.h |  1 +
 lib/meta-flow.c | 13 ++
 ofproto/ofproto-dpif-xlate.c| 12 ++
 tests/system-traffic.at | 42 +
 4 files changed, 68 insertions(+)

diff --git a/include/openvswitch/meta-flow.h b/include/openvswitch/meta-flow.h
index 95e52e358..045dce8f5 100644
--- a/include/openvswitch/meta-flow.h
+++ b/include/openvswitch/meta-flow.h
@@ -2305,6 +2305,7 @@ void mf_set_flow_value_masked(const struct mf_field *,
   const union mf_value *mask,
   struct flow *);
 bool mf_is_tun_metadata(const struct mf_field *);
+bool mf_is_frozen_metadata(const struct mf_field *);
 bool mf_is_pipeline_field(const struct mf_field *);
 bool mf_is_set(const struct mf_field *, const struct flow *);
 void mf_mask_field(const struct mf_field *, struct flow_wildcards *);
diff --git a/lib/meta-flow.c b/lib/meta-flow.c
index c808d205d..e03cd8d0c 100644
--- a/lib/meta-flow.c
+++ b/lib/meta-flow.c
@@ -1788,6 +1788,19 @@ mf_is_tun_metadata(const struct mf_field *mf)
mf->id < MFF_TUN_METADATA0 + TUN_METADATA_NUM_OPTS;
 }
 
+bool
+mf_is_frozen_metadata(const struct mf_field *mf)
+{
+if (mf->id >= MFF_TUN_ID && mf->id <= MFF_IN_PORT_OXM) {
+return true;
+}
+
+if (mf->id >= MFF_REG0 && mf->id < MFF_ETH_SRC) {
+return true;
+}
+return false;
+}
+
 bool
 mf_is_pipeline_field(const struct mf_field *mf)
 {
diff --git a/ofproto/ofproto-dpif-xlate.c b/ofproto/ofproto-dpif-xlate.c
index 7108c8a30..14d00db1e 100644
--- a/ofproto/ofproto-dpif-xlate.c
+++ b/ofproto/ofproto-dpif-xlate.c
@@ -6195,6 +6195,18 @@ compose_conntrack_action(struct xlate_ctx *ctx, struct 
ofpact_conntrack *ofc,
 
 if (ofc->zone_src.field) {
 zone = mf_get_subfield(>zone_src, >xin->flow);
+if (ctx->xin->frozen_state) {
+/* If the upcall is a resume of a recirculation, we only need to
+ * unwildcard the fields that are not in the frozen_metadata, as
+ * when the rules update, OVS will generate a new recirc_id,
+ * which will invalidate the megaflow with old the recirc_id.
+ */
+if (!mf_is_frozen_metadata(ofc->zone_src.field)) {
+mf_mask_field(ofc->zone_src.field, ctx->wc);
+}
+} else {
+mf_mask_field(ofc->zone_src.field, ctx->wc);
+}
 } else {
 zone = ofc->zone_imm;
 }
diff --git a/tests/system-traffic.at b/tests/system-traffic.at
index fb5b9a36d..84a9759ea 100644
--- a/tests/system-traffic.at
+++ b/tests/system-traffic.at
@@ -1927,6 +1927,48 @@ 
tcp,orig=(src=10.1.1.3,dst=10.1.1.4,sport=,dport=),reply=(src=
 OVS_TRAFFIC_VSWITCHD_STOP
 AT_CLEANUP
 
+AT_SETUP([conntrack - zones from other field])
+CHECK_CONNTRACK()
+OVS_TRAFFIC_VSWITCHD_START()
+
+ADD_NAMESPACES(at_ns0, at_ns1)
+
+ADD_VETH(p0, at_ns0, br0, "10.1.1.1/24")
+ADD_VETH(p1, at_ns1, br0, "10.1.1.2/24")
+
+dnl Allow any traffic from ns0->ns1. Only allow nd, return traffic from 
ns1->ns0.

Re: [ovs-dev] [PATCH ovn branch-20.06 00/15] Backport rollup

2021-02-18 Thread Dumitru Ceara

On 2/18/21 9:09 AM, Frode Nordahl wrote:

Hello all,


Hi Frode,

Many thanks for this!



In Ubuntu we have backported a set of fixes to our OVN 20.06 and OVN
20.03 packages.  In preparing for new point releases for OVN 20.06
and OVN 20.03, we would very much like to add these patches to the
upstream branches.

The issues solved for OVN 20.06 with these patches are:

   * Fix for upgrading database schema of clustered databases on package
 upgrade (LP: #1907081)[0]
   * Fixes for predictable resolution for conflicting flow actions.
 (LP: #1906922)[1]


You might want to wait a bit with releasing new packages and include 
more patches (some are not merged in upstream master yet) that fix 
crashes due some of the ofctrl changes:


https://github.com/ovn-org/ovn/commit/858d1dd716db1a1e664a7c1737fd34f04fcbda5e 
(in upstream master and branch20.12)


http://patchwork.ozlabs.org/project/ovn/patch/1613490806-11143-1-git-send-email-dce...@redhat.com/ 
(I'll be submitting a v2 today).


Regards,
Dumitru

___
dev mailing list
d...@openvswitch.org
https://mail.openvswitch.org/mailman/listinfo/ovs-dev


Re: [ovs-dev] [PATCH] Documentation: Fix DPDK qos example.

2021-02-18 Thread Eelco Chaudron



On 17 Feb 2021, at 18:41, William Tu wrote:

>>
  Information Rate). High priority traffic is routed to queue 10,
 which marks
  all traffic as CIR, i.e. Green. All low priority traffic, queue 20,
 is
  marked as EIR, i.e. Yellow::

  $ ovs-vsctl --timeout=5 set port dpdk1 qos=@myqos -- \
  --id=@myqos create qos type=trtcm-policer \
 -other-config:cir=52000 other-config:cbs=2048 \
 -other-config:eir=52000 other-config:ebs=2048  \
>>
>> 52000 is fine as our documentation states cir, eir are in bytes per
>> second, minus the ethernet header.
>> So (64-12) * 1000 = 52000
>
> How come it's not minus 14-byte ethernet header?

You are right, it should be 14, miscounted the rte_ether_hdr structure size :(

___
dev mailing list
d...@openvswitch.org
https://mail.openvswitch.org/mailman/listinfo/ovs-dev


Re: [ovs-dev] [PATCH ovn branch-20.03 01/16] ovn-ctl: Handle cluster db upgrades for run_(nb/sb)_ovsdb

2021-02-18 Thread 0-day Robot
Bleep bloop.  Greetings Frode Nordahl, I am a robot and I have tried out your 
patch.
Thanks for your contribution.

I encountered some error that I wasn't expecting.  See the details below.


checkpatch:
WARNING: Unexpected sign-offs from developers who are not authors or co-authors 
or committers: Frode Nordahl 
WARNING: Line is 91 characters long (recommended limit is 79)
#35 FILE: utilities/ovn-ctl:289:
if test X$detach = Xno && test $mode = cluster && test -z 
"$cluster_remote_addr" ; then

Lines checked: 64, Warnings: 2, Errors: 0


build:
gcc -std=gnu99 -DHAVE_CONFIG_H -I.   -I ./include  -I ./include -I ./ovn -I 
./include -I 
/var/lib/jenkins/jobs/0day_robot_upstream_build_ovn_from_pw/workspace/OVSDIR/include
 -I 
/var/lib/jenkins/jobs/0day_robot_upstream_build_ovn_from_pw/workspace/OVSDIR/include
 -I 
/var/lib/jenkins/jobs/0day_robot_upstream_build_ovn_from_pw/workspace/OVSDIR/lib
 -I 
/var/lib/jenkins/jobs/0day_robot_upstream_build_ovn_from_pw/workspace/OVSDIR/lib
 -I 
/var/lib/jenkins/jobs/0day_robot_upstream_build_ovn_from_pw/workspace/OVSDIR -I 
/var/lib/jenkins/jobs/0day_robot_upstream_build_ovn_from_pw/workspace/OVSDIR -I 
./lib -I ./lib-Wstrict-prototypes -Wall -Wextra -Wno-sign-compare 
-Wpointer-arith -Wformat -Wformat-security -Wswitch-enum -Wunused-parameter 
-Wbad-function-cast -Wcast-align -Wstrict-prototypes -Wold-style-definition 
-Wmissing-prototypes -Wmissing-field-initializers -fno-strict-aliasing -Wshadow 
-Werror -Werror  -g -O2 -MT controller/pinctrl.o -MD -MP -MF $depbase.Tpo -c -o 
controller/pinctrl.o controller/pinctrl.c &&\
mv -f $depbase.Tpo $depbase.Po
depbase=`echo controller/patch.o | sed 's|[^/]*$|.deps/&|;s|\.o$||'`;\
gcc -std=gnu99 -DHAVE_CONFIG_H -I.   -I ./include  -I ./include -I ./ovn -I 
./include -I 
/var/lib/jenkins/jobs/0day_robot_upstream_build_ovn_from_pw/workspace/OVSDIR/include
 -I 
/var/lib/jenkins/jobs/0day_robot_upstream_build_ovn_from_pw/workspace/OVSDIR/include
 -I 
/var/lib/jenkins/jobs/0day_robot_upstream_build_ovn_from_pw/workspace/OVSDIR/lib
 -I 
/var/lib/jenkins/jobs/0day_robot_upstream_build_ovn_from_pw/workspace/OVSDIR/lib
 -I 
/var/lib/jenkins/jobs/0day_robot_upstream_build_ovn_from_pw/workspace/OVSDIR -I 
/var/lib/jenkins/jobs/0day_robot_upstream_build_ovn_from_pw/workspace/OVSDIR -I 
./lib -I ./lib-Wstrict-prototypes -Wall -Wextra -Wno-sign-compare 
-Wpointer-arith -Wformat -Wformat-security -Wswitch-enum -Wunused-parameter 
-Wbad-function-cast -Wcast-align -Wstrict-prototypes -Wold-style-definition 
-Wmissing-prototypes -Wmissing-field-initializers -fno-strict-aliasing -Wshadow 
-Werror -Werror  -g -O2 -MT controller/patch.o -MD -MP -MF $depbase.Tpo -c -o 
controller/patch.o controller/patch.c &&\
mv -f $depbase.Tpo $depbase.Po
depbase=`echo controller/ovn-controller.o | sed 's|[^/]*$|.deps/&|;s|\.o$||'`;\
gcc -std=gnu99 -DHAVE_CONFIG_H -I.   -I ./include  -I ./include -I ./ovn -I 
./include -I 
/var/lib/jenkins/jobs/0day_robot_upstream_build_ovn_from_pw/workspace/OVSDIR/include
 -I 
/var/lib/jenkins/jobs/0day_robot_upstream_build_ovn_from_pw/workspace/OVSDIR/include
 -I 
/var/lib/jenkins/jobs/0day_robot_upstream_build_ovn_from_pw/workspace/OVSDIR/lib
 -I 
/var/lib/jenkins/jobs/0day_robot_upstream_build_ovn_from_pw/workspace/OVSDIR/lib
 -I 
/var/lib/jenkins/jobs/0day_robot_upstream_build_ovn_from_pw/workspace/OVSDIR -I 
/var/lib/jenkins/jobs/0day_robot_upstream_build_ovn_from_pw/workspace/OVSDIR -I 
./lib -I ./lib-Wstrict-prototypes -Wall -Wextra -Wno-sign-compare 
-Wpointer-arith -Wformat -Wformat-security -Wswitch-enum -Wunused-parameter 
-Wbad-function-cast -Wcast-align -Wstrict-prototypes -Wold-style-definition 
-Wmissing-prototypes -Wmissing-field-initializers -fno-strict-aliasing -Wshadow 
-Werror -Werror  -g -O2 -MT controller/ovn-controller.o -MD -MP -MF 
$depbase.Tpo -c -o controller/ovn-controller.o controller/ovn-controller.c &&\
mv -f $depbase.Tpo $depbase.Po
depbase=`echo controller/physical.o | sed 's|[^/]*$|.deps/&|;s|\.o$||'`;\
gcc -std=gnu99 -DHAVE_CONFIG_H -I.   -I ./include  -I ./include -I ./ovn -I 
./include -I 
/var/lib/jenkins/jobs/0day_robot_upstream_build_ovn_from_pw/workspace/OVSDIR/include
 -I 
/var/lib/jenkins/jobs/0day_robot_upstream_build_ovn_from_pw/workspace/OVSDIR/include
 -I 
/var/lib/jenkins/jobs/0day_robot_upstream_build_ovn_from_pw/workspace/OVSDIR/lib
 -I 
/var/lib/jenkins/jobs/0day_robot_upstream_build_ovn_from_pw/workspace/OVSDIR/lib
 -I 
/var/lib/jenkins/jobs/0day_robot_upstream_build_ovn_from_pw/workspace/OVSDIR -I 
/var/lib/jenkins/jobs/0day_robot_upstream_build_ovn_from_pw/workspace/OVSDIR -I 
./lib -I ./lib-Wstrict-prototypes -Wall -Wextra -Wno-sign-compare 
-Wpointer-arith -Wformat -Wformat-security -Wswitch-enum -Wunused-parameter 
-Wbad-function-cast -Wcast-align -Wstrict-prototypes -Wold-style-definition 
-Wmissing-prototypes -Wmissing-field-initializers -fno-strict-aliasing -Wshadow 
-Werror -Werror  -g -O2 -MT controller/physical.o -MD -MP -MF $depbase.Tpo -c 
-o 

Re: [ovs-dev] [PATCH ovn branch-20.06 04/15] ofctrl: Incremental processing for flow installation by tracking.

2021-02-18 Thread 0-day Robot
Bleep bloop.  Greetings Frode Nordahl, I am a robot and I have tried out your 
patch.
Thanks for your contribution.

I encountered some error that I wasn't expecting.  See the details below.


git-am:
error: patch fragment without header at line 127: @@ -861,6 +955,7 @@ 
ofctrl_check_and_add_flow(struct ovn_desired_flow_table *flow_table,
error: could not build fake ancestor
hint: Use 'git am --show-current-patch' to see the failed patch
Patch failed at 0001 ofctrl: Incremental processing for flow installation by 
tracking.
When you have resolved this problem, run "git am --continue".
If you prefer to skip this patch, run "git am --skip" instead.
To restore the original branch and stop patching, run "git am --abort".


Please check this out.  If you feel there has been an error, please email 
acon...@redhat.com

Thanks,
0-day Robot
___
dev mailing list
d...@openvswitch.org
https://mail.openvswitch.org/mailman/listinfo/ovs-dev


[ovs-dev] [PATCH ovn branch-20.03 16/16] tests: Fix test "ovn -- Superseding ACLs with conjunction".

2021-02-18 Thread Frode Nordahl
From: Dumitru Ceara 

The test was checking the output of "ovs-ofctl dump-flows" without
taking into account that some fields don't have predictable values,
e.g., hard_age.

Instead, use ofctl_strip_all().

Fixes: 986b3d5e4ad6 ("ofctrl.c: Add a predictable resolution for conflicting 
flow actions.")
Reported-by: Numan Siddique 
Signed-off-by: Dumitru Ceara 
Signed-off-by: Numan Siddique 
(cherry picked from commit 6e3d69e6b5153e26c869a03ec7dd1aaa40488005)
(patch was adapted to branch-20.03 by checking table 44 not 45)
Signed-off-by: Frode Nordahl 
---
 tests/ovn.at | 72 ++--
 1 file changed, 36 insertions(+), 36 deletions(-)

diff --git a/tests/ovn.at b/tests/ovn.at
index 55d4784b7..7cda84428 100644
--- a/tests/ovn.at
+++ b/tests/ovn.at
@@ -12653,16 +12653,16 @@ ovn-nbctl acl-add ls1 to-lport 3 'ip4.src==10.0.0.1' 
allow
 ovn-nbctl --wait=hv sync
 
 # Check OVS flows, the less restrictive flows should have been installed.
-AT_CHECK([as hv1 ovs-ofctl dump-flows br-int table=45 | \
-grep "priority=1003" | awk '{print $7 " " $8}' | \
+AT_CHECK([as hv1 ovs-ofctl dump-flows br-int table=44 | ofctl_strip_all | \
+grep "priority=1003" | \
 sed 's/conjunction([[^)]]*)/conjunction()/g' | sort], [0], [dnl
-priority=1003,conj_id=2,ip,metadata=0x1 actions=resubmit(,46)
-priority=1003,conj_id=3,ip,metadata=0x1 actions=resubmit(,46)
-priority=1003,ip,metadata=0x1,nw_dst=10.0.0.3 
actions=conjunction(),conjunction()
-priority=1003,ip,metadata=0x1,nw_dst=10.0.0.4 
actions=conjunction(),conjunction()
-priority=1003,ip,metadata=0x1,nw_src=10.0.0.1 actions=resubmit(,46)
-priority=1003,ip,metadata=0x1,nw_src=10.0.0.2 actions=conjunction()
-priority=1003,ip,metadata=0x1,nw_src=10.0.0.42 actions=conjunction()
+ table=44, priority=1003,conj_id=2,ip,metadata=0x1 actions=resubmit(,45)
+ table=44, priority=1003,conj_id=3,ip,metadata=0x1 actions=resubmit(,45)
+ table=44, priority=1003,ip,metadata=0x1,nw_dst=10.0.0.3 
actions=conjunction(),conjunction()
+ table=44, priority=1003,ip,metadata=0x1,nw_dst=10.0.0.4 
actions=conjunction(),conjunction()
+ table=44, priority=1003,ip,metadata=0x1,nw_src=10.0.0.1 actions=resubmit(,45)
+ table=44, priority=1003,ip,metadata=0x1,nw_src=10.0.0.2 actions=conjunction()
+ table=44, priority=1003,ip,metadata=0x1,nw_src=10.0.0.42 actions=conjunction()
 ])
 
 # Traffic 10.0.0.1, 10.0.0.2 -> 10.0.0.3, 10.0.0.4 should be allowed.
@@ -12699,16 +12699,16 @@ ovn-nbctl acl-del ls1 to-lport 3 'ip4.src==10.0.0.1 
|| ip4.src==10.0.0.1'
 ovn-nbctl --wait=hv sync
 
 # Check OVS flows, the second less restrictive allow ACL should have been 
installed.
-AT_CHECK([as hv1 ovs-ofctl dump-flows br-int table=45 | \
-grep "priority=1003" | awk '{print $7 " " $8}' | \
+AT_CHECK([as hv1 ovs-ofctl dump-flows br-int table=44 | ofctl_strip_all | \
+grep "priority=1003" | \
 sed 's/conjunction([[^)]]*)/conjunction()/g' | sort], [0], [dnl
-priority=1003,conj_id=2,ip,metadata=0x1 actions=resubmit(,46)
-priority=1003,conj_id=3,ip,metadata=0x1 actions=resubmit(,46)
-priority=1003,ip,metadata=0x1,nw_dst=10.0.0.3 
actions=conjunction(),conjunction()
-priority=1003,ip,metadata=0x1,nw_dst=10.0.0.4 
actions=conjunction(),conjunction()
-priority=1003,ip,metadata=0x1,nw_src=10.0.0.1 actions=resubmit(,46)
-priority=1003,ip,metadata=0x1,nw_src=10.0.0.2 actions=conjunction()
-priority=1003,ip,metadata=0x1,nw_src=10.0.0.42 actions=conjunction()
+ table=44, priority=1003,conj_id=2,ip,metadata=0x1 actions=resubmit(,45)
+ table=44, priority=1003,conj_id=3,ip,metadata=0x1 actions=resubmit(,45)
+ table=44, priority=1003,ip,metadata=0x1,nw_dst=10.0.0.3 
actions=conjunction(),conjunction()
+ table=44, priority=1003,ip,metadata=0x1,nw_dst=10.0.0.4 
actions=conjunction(),conjunction()
+ table=44, priority=1003,ip,metadata=0x1,nw_src=10.0.0.1 actions=resubmit(,45)
+ table=44, priority=1003,ip,metadata=0x1,nw_src=10.0.0.2 actions=conjunction()
+ table=44, priority=1003,ip,metadata=0x1,nw_src=10.0.0.42 actions=conjunction()
 ])
 
 # Remove the less restrictive allow ACL.
@@ -12716,16 +12716,16 @@ ovn-nbctl acl-del ls1 to-lport 3 'ip4.src==10.0.0.1'
 ovn-nbctl --wait=hv sync
 
 # Check OVS flows, the 10.0.0.1 conjunction should have been reinstalled.
-AT_CHECK([as hv1 ovs-ofctl dump-flows br-int table=45 | \
-grep "priority=1003" | awk '{print $7 " " $8}' | \
+AT_CHECK([as hv1 ovs-ofctl dump-flows br-int table=44 | ofctl_strip_all | \
+grep "priority=1003" | \
 sed 's/conjunction([[^)]]*)/conjunction()/g' | sort], [0], [dnl
-priority=1003,conj_id=2,ip,metadata=0x1 actions=resubmit(,46)
-priority=1003,conj_id=3,ip,metadata=0x1 actions=resubmit(,46)
-priority=1003,ip,metadata=0x1,nw_dst=10.0.0.3 
actions=conjunction(),conjunction()
-priority=1003,ip,metadata=0x1,nw_dst=10.0.0.4 
actions=conjunction(),conjunction()
-priority=1003,ip,metadata=0x1,nw_src=10.0.0.1 
actions=conjunction(),conjunction()
-priority=1003,ip,metadata=0x1,nw_src=10.0.0.2 actions=conjunction()

[ovs-dev] [PATCH ovn branch-20.03 07/16] ofctrl.c: Fix duplicated flow handling in I-P while merging opposite changes.

2021-02-18 Thread Frode Nordahl
From: Han Zhou 

In a scenario in I-P when a desired flow is removed and an exactly same flow is
added back in the same iteration, the merge_tracked_flows() function will merge
the operation without firing any OpenFlow action. However, if there are
multiple desired flows (e.g. F1 and F2) matching the same installed flow, and
if the one being re-added (say, F1) is the one currently installed in OVS, the
current implementation will update the currently installed flow to F2 in the
data structure while the actual OVS flow is not updated (still F1). So far
there is still no problem, but the member desired_flow of the installed flow
is pointing to the wrong desired flow.

Now there is only one place where the desired_flow member is consulted, in
update_installed_flows_by_track() for handling a tracked *modified* flow. In
reality flow modification happens only when conjunction flows need to be
combined, which would never happen together with the above scenario of
merge_tracked_flows(). So this wrong desired_flow pointer doesn't cause any
real problem yet.

However, there is a place that can already utilize this active desired_flow
information, which is when handling a tracked flow deletion in
update_installed_flows_by_track(): we can check if the flow being deleted is
the currently active one installed in OVS. If not, we don't need to send and
OpenFlow modify to OVS. This optimization is added in this patch, apart from
fixing the problem of merge_tracked_flows(). Without the fix, this optimization
would cause the test case added in this patch fail.

Fixes: f4e508dd7 ("ofctrl.c: Merge opposite changes of tracked flows before 
installing.")
Acked-by: Dumitru Ceara 
Signed-off-by: Han Zhou 
(cherry picked from commit 9d2e8d32fb9865513b70408a665184a67564390d)
Signed-off-by: Frode Nordahl 
---
 controller/ofctrl.c |  28 +++-
 tests/ovn.at| 108 
 2 files changed, 134 insertions(+), 2 deletions(-)

diff --git a/controller/ofctrl.c b/controller/ofctrl.c
index b526c68f4..41495c41f 100644
--- a/controller/ofctrl.c
+++ b/controller/ofctrl.c
@@ -788,6 +788,24 @@ ofctrl_recv(const struct ofp_header *oh, enum ofptype type)
 }
 }
 
+/* Returns true if a desired flow is active (the one currently installed
+ * among the list of desired flows that are linked to the same installed
+ * flow). */
+static inline bool
+desired_flow_is_active(struct desired_flow *d)
+{
+return (d->installed_flow && d->installed_flow->desired_flow == d);
+}
+
+/* Set a desired flow as the active one among the list of desired flows
+ * that are linked to the same installed flow. */
+static inline void
+desired_flow_set_active(struct desired_flow *d)
+{
+ovs_assert(d->installed_flow);
+d->installed_flow->desired_flow = d;
+}
+
 static void
 link_installed_to_desired(struct installed_flow *i, struct desired_flow *d)
 {
@@ -1679,6 +1697,8 @@ merge_tracked_flows(struct ovn_desired_flow_table 
*flow_table)
 /* del_f must have been installed, otherwise it should have been
  * removed during track_flow_add_or_modify. */
 ovs_assert(del_f->installed_flow);
+
+bool del_f_was_active = desired_flow_is_active(del_f);
 if (!f->installed_flow) {
 /* f is not installed yet. */
 struct installed_flow *i = del_f->installed_flow;
@@ -1690,6 +1710,9 @@ merge_tracked_flows(struct ovn_desired_flow_table 
*flow_table)
 ovs_assert(f->installed_flow == del_f->installed_flow);
 unlink_installed_to_desired(del_f->installed_flow, del_f);
 }
+if (del_f_was_active) {
+desired_flow_set_active(f);
+}
 hmap_remove(_flows, _f->match_hmap_node);
 ovs_list_remove(_f->track_list_node);
 desired_flow_destroy(del_f);
@@ -1717,6 +1740,7 @@ update_installed_flows_by_track(struct 
ovn_desired_flow_table *flow_table,
 /* The desired flow was deleted */
 if (f->installed_flow) {
 struct installed_flow *i = f->installed_flow;
+bool was_active = desired_flow_is_active(f);
 unlink_installed_to_desired(i, f);
 
 if (!i->desired_flow) {
@@ -1725,7 +1749,7 @@ update_installed_flows_by_track(struct 
ovn_desired_flow_table *flow_table,
 
 hmap_remove(_flows, >match_hmap_node);
 installed_flow_destroy(i);
-} else {
+} else if (was_active) {
 /* There are other desired flow(s) referencing this
  * installed flow, so update the OVS flow for the new
  * active flow (at least the cookie will be different,
@@ -1749,7 +1773,7 @@ update_installed_flows_by_track(struct 
ovn_desired_flow_table *flow_table,
 hmap_insert(_flows, _node->match_hmap_node,
 

[ovs-dev] [PATCH ovn branch-20.03 15/16] tests: Add ofctl_strip_all() to filter OVS flow outputs.

2021-02-18 Thread Frode Nordahl
From: Dumitru Ceara 

Extend the already existing ofctl_strip() to also ignore n_packets,
n_bytes, cookie.  Use some helper functions from
tests/system-userspace-packet-type-aware.at, which will be removed
by a future commit.

Signed-off-by: Dumitru Ceara 
Signed-off-by: Numan Siddique 
(cherry picked from commit 0879a0aa9f332bdc689769a1bc2f156f1c3149a5)
Signed-off-by: Frode Nordahl 
---
 tests/ofproto-macros.at | 23 ++-
 1 file changed, 22 insertions(+), 1 deletion(-)

diff --git a/tests/ofproto-macros.at b/tests/ofproto-macros.at
index 6c4ff60e7..22999c1ca 100644
--- a/tests/ofproto-macros.at
+++ b/tests/ofproto-macros.at
@@ -1,12 +1,27 @@
 m4_divert_push([PREPARE_TESTS])
 [
+# Strips 'n_packets=...' from ovs-ofctl output.
+strip_n_packets () {
+sed 's/ n_packets=[0-9]*,//'
+}
+
+# Strips 'n_bytes=...' from ovs-ofctl output.
+strip_n_bytes () {
+sed 's/ n_bytes=[0-9]*,//'
+}
+
+# Strips 'cookie=...' from ovs-ofctl output.
+strip_cookie () {
+sed 's/ cookie=0x[0-9a-fA-F]*,//'
+}
+
 # Strips out uninteresting parts of ovs-ofctl output, as well as parts
 # that vary from one run to another.
 ofctl_strip () {
 sed '
 s/ (xid=0x[0-9a-fA-F]*)//
 s/ duration=[0-9.]*s,//
-s/ cookie=0x0,//
+s/ cookie=0,//
 s/ table=0,//
 s/ n_packets=0,//
 s/ n_bytes=0,//
@@ -19,6 +34,12 @@ s/dir\/[0-9]*\/br0.mgmt/dir\/\/br0.mgmt/
 '
 }
 
+# Strips out uninteresting parts of ovs-ofctl output, including n_packets=..
+# n_bytes=..
+ofctl_strip_all () {
+ofctl_strip | strip_n_packets | strip_n_bytes | strip_cookie
+}
+
 # Filter (multiline) vconn debug messages from ovs-vswitchd.log.
 # Use with vconn_sub() and ofctl_strip()
 print_vconn_debug () { awk -F\| < ovs-vswitchd.log '
-- 
2.30.0

___
dev mailing list
d...@openvswitch.org
https://mail.openvswitch.org/mailman/listinfo/ovs-dev


[ovs-dev] [PATCH ovn branch-20.03 14/16] ovn.at: Make some of the tests more predictable.

2021-02-18 Thread Frode Nordahl
From: Dumitru Ceara 

Fix some of the race conditions that are present in the current OVN test
suite.

Signed-off-by: Dumitru Ceara 
Signed-off-by: Ben Pfaff 
(cherry picked from commit d6594a4695084e1b0f4fb3170547942876d3a81a)
Signed-off-by: Frode Nordahl 
---
 tests/ovn.at | 48 +++-
 1 file changed, 27 insertions(+), 21 deletions(-)

diff --git a/tests/ovn.at b/tests/ovn.at
index b186adefb..55d4784b7 100644
--- a/tests/ovn.at
+++ b/tests/ovn.at
@@ -3417,6 +3417,7 @@ for i in 1 2 3; do
 ovn-nbctl lsp-set-addresses lp$i$j "f0:00:00:00:00:$i$j 
192.168.0.$i$j" "$extra_addr"
 ovn-nbctl lsp-set-port-security lp$i$j "f0:00:00:00:00:$i$j 
192.168.0.$i$j" "$extra_addr"
 fi
+OVS_WAIT_UNTIL([test x`ovn-nbctl lsp-get-up lp$i$j` = xup])
 done
 done
 
@@ -12653,14 +12654,15 @@ ovn-nbctl --wait=hv sync
 
 # Check OVS flows, the less restrictive flows should have been installed.
 AT_CHECK([as hv1 ovs-ofctl dump-flows br-int table=45 | \
-grep "priority=1003" | awk '{print $7 " " $8}' | sort], [0], [dnl
+grep "priority=1003" | awk '{print $7 " " $8}' | \
+sed 's/conjunction([[^)]]*)/conjunction()/g' | sort], [0], [dnl
 priority=1003,conj_id=2,ip,metadata=0x1 actions=resubmit(,46)
 priority=1003,conj_id=3,ip,metadata=0x1 actions=resubmit(,46)
-priority=1003,ip,metadata=0x1,nw_dst=10.0.0.3 
actions=conjunction(2,1/2),conjunction(3,1/2)
-priority=1003,ip,metadata=0x1,nw_dst=10.0.0.4 
actions=conjunction(2,1/2),conjunction(3,1/2)
+priority=1003,ip,metadata=0x1,nw_dst=10.0.0.3 
actions=conjunction(),conjunction()
+priority=1003,ip,metadata=0x1,nw_dst=10.0.0.4 
actions=conjunction(),conjunction()
 priority=1003,ip,metadata=0x1,nw_src=10.0.0.1 actions=resubmit(,46)
-priority=1003,ip,metadata=0x1,nw_src=10.0.0.2 actions=conjunction(2,2/2)
-priority=1003,ip,metadata=0x1,nw_src=10.0.0.42 actions=conjunction(3,2/2)
+priority=1003,ip,metadata=0x1,nw_src=10.0.0.2 actions=conjunction()
+priority=1003,ip,metadata=0x1,nw_src=10.0.0.42 actions=conjunction()
 ])
 
 # Traffic 10.0.0.1, 10.0.0.2 -> 10.0.0.3, 10.0.0.4 should be allowed.
@@ -12698,14 +12700,15 @@ ovn-nbctl --wait=hv sync
 
 # Check OVS flows, the second less restrictive allow ACL should have been 
installed.
 AT_CHECK([as hv1 ovs-ofctl dump-flows br-int table=45 | \
-grep "priority=1003" | awk '{print $7 " " $8}' | sort], [0], [dnl
+grep "priority=1003" | awk '{print $7 " " $8}' | \
+sed 's/conjunction([[^)]]*)/conjunction()/g' | sort], [0], [dnl
 priority=1003,conj_id=2,ip,metadata=0x1 actions=resubmit(,46)
 priority=1003,conj_id=3,ip,metadata=0x1 actions=resubmit(,46)
-priority=1003,ip,metadata=0x1,nw_dst=10.0.0.3 
actions=conjunction(2,1/2),conjunction(3,1/2)
-priority=1003,ip,metadata=0x1,nw_dst=10.0.0.4 
actions=conjunction(2,1/2),conjunction(3,1/2)
+priority=1003,ip,metadata=0x1,nw_dst=10.0.0.3 
actions=conjunction(),conjunction()
+priority=1003,ip,metadata=0x1,nw_dst=10.0.0.4 
actions=conjunction(),conjunction()
 priority=1003,ip,metadata=0x1,nw_src=10.0.0.1 actions=resubmit(,46)
-priority=1003,ip,metadata=0x1,nw_src=10.0.0.2 actions=conjunction(2,2/2)
-priority=1003,ip,metadata=0x1,nw_src=10.0.0.42 actions=conjunction(3,2/2)
+priority=1003,ip,metadata=0x1,nw_src=10.0.0.2 actions=conjunction()
+priority=1003,ip,metadata=0x1,nw_src=10.0.0.42 actions=conjunction()
 ])
 
 # Remove the less restrictive allow ACL.
@@ -12714,14 +12717,15 @@ ovn-nbctl --wait=hv sync
 
 # Check OVS flows, the 10.0.0.1 conjunction should have been reinstalled.
 AT_CHECK([as hv1 ovs-ofctl dump-flows br-int table=45 | \
-grep "priority=1003" | awk '{print $7 " " $8}' | sort], [0], [dnl
+grep "priority=1003" | awk '{print $7 " " $8}' | \
+sed 's/conjunction([[^)]]*)/conjunction()/g' | sort], [0], [dnl
 priority=1003,conj_id=2,ip,metadata=0x1 actions=resubmit(,46)
 priority=1003,conj_id=3,ip,metadata=0x1 actions=resubmit(,46)
-priority=1003,ip,metadata=0x1,nw_dst=10.0.0.3 
actions=conjunction(2,1/2),conjunction(3,1/2)
-priority=1003,ip,metadata=0x1,nw_dst=10.0.0.4 
actions=conjunction(2,1/2),conjunction(3,1/2)
-priority=1003,ip,metadata=0x1,nw_src=10.0.0.1 
actions=conjunction(2,2/2),conjunction(3,2/2)
-priority=1003,ip,metadata=0x1,nw_src=10.0.0.2 actions=conjunction(2,2/2)
-priority=1003,ip,metadata=0x1,nw_src=10.0.0.42 actions=conjunction(3,2/2)
+priority=1003,ip,metadata=0x1,nw_dst=10.0.0.3 
actions=conjunction(),conjunction()
+priority=1003,ip,metadata=0x1,nw_dst=10.0.0.4 
actions=conjunction(),conjunction()
+priority=1003,ip,metadata=0x1,nw_src=10.0.0.1 
actions=conjunction(),conjunction()
+priority=1003,ip,metadata=0x1,nw_src=10.0.0.2 actions=conjunction()
+priority=1003,ip,metadata=0x1,nw_src=10.0.0.42 actions=conjunction()
 ])
 
 # Traffic 10.0.0.1, 10.0.0.2 -> 10.0.0.3, 10.0.0.4 should be allowed.
@@ -12752,14 +12756,15 @@ ovn-nbctl --wait=hv sync
 
 # Check OVS flows, the less restrictive flows should have been installed.
 AT_CHECK([as hv1 ovs-ofctl dump-flows 

[ovs-dev] [PATCH ovn branch-20.03 05/16] ofctrl: Incremental processing for flow installation by tracking.

2021-02-18 Thread Frode Nordahl
From: Han Zhou 

With incremental processing for flow computation, the bottle neck of
ovn-controller in large scale environment is in the flow installation
(ofctrl_put()), which does full comparison between the two big flow tables: the
installed flows and desired flows.

This patch implements tracking desired flow changes when flows are
incrementally computed by I-P engine, and then incrementally processing the
flow installation using the tracked information in ofctrl_put(). It falls back
to the full comparison whenever tracking information is unavailable, e.g. when
I-P engine triggers full recompute.

In ovn-scale-test with 3000 HVs and 30k lports, the end-to-end latency between
the moment a lflow is updated in SB DB and the moment when all the 3K HVs
complete OVS flow updating has reduced around 60% (from 1s to 400ms).

Below is the perf result for a ovn-controller processing a new port-binding:

Beore:
+   96.76% 0.00%  ovn-controller  [unknown]   [k] 0x
+   90.21% 0.00%  ovn-controller  ovn-controller  [.] main
+   39.93% 1.19%  ovn-controller  ovn-controller  [.] ofctrl_put
+   31.27%12.47%  ovn-controller  ovn-controller  [.] ovn_flow_lookup
+   22.12% 3.12%  ovn-controller  ovn-controller  [.] encaps_run
+   18.69% 2.77%  ovn-controller  ovn-controller  [.] minimatch_equal
+   17.63% 4.11%  ovn-controller  ovn-controller  [.] patch_run
+   15.91% 0.00%  ovn-controller  ovn-controller  [.] 
add_bridge_mappings (inlined)
+   14.03%12.08%  ovn-controller  ovn-controller  [.] minimask_equal
+   12.41% 0.00%  ovn-controller  ovn-controller  [.] 
chassis_tunnel_add (inlined)
+   11.40% 0.00%  ovn-controller  ovn-controller  [.] tunnel_add 
(inlined)

After:
+   94.59% 0.00%  ovn-controller  [unknown]   [k] 0x
+   83.56% 0.09%  ovn-controller  ovn-controller  [.] main
+   35.37% 3.13%  ovn-controller  ovn-controller  [.] encaps_run
+   27.54% 7.53%  ovn-controller  ovn-controller  [.] patch_run
+   24.86% 0.00%  ovn-controller  ovn-controller  [.] 
add_bridge_mappings (inlined)
+   20.01% 0.00%  ovn-controller  ovn-controller  [.] 
chassis_tunnel_add (inlined)
+   18.51% 0.00%  ovn-controller  ovn-controller  [.] tunnel_add 
(inlined)
+   14.08% 0.17%  ovn-controller  ovn-controller  [.] physical_run
+   11.37%11.28%  ovn-controller  ovn-controller  [.] next_real_row
+   10.50% 2.59%  ovn-controller  ovn-controller  [.] 
consider_port_binding
...
+2.14% 0.32%  ovn-controller  ovn-controller  [.] ofctrl_put


 ▒

Before the optimization, ofctrl_put took 40% of CPU, and now it disappears from
the hot spots.

Acked-by: Mark Michelson 
Signed-off-by: Han Zhou 
(cherry picked from commit 6f0b1e02d9ab3a94048c4818f2d382938cad4b71)
Signed-off-by: Frode Nordahl 
---
 controller/ofctrl.c | 289 +++-
 controller/ofctrl.h |   6 +-
 2 files changed, 240 insertions(+), 55 deletions(-)

diff --git a/controller/ofctrl.c b/controller/ofctrl.c
index 6de14ac9d..3ff8604b1 100644
--- a/controller/ofctrl.c
+++ b/controller/ofctrl.c
@@ -101,6 +101,39 @@ struct ovn_flow {
  *
  * The links are updated whenever there is a change in desired flows, which is
  * usually triggered by a SB data change in I-P engine.
+ *
+ * ** Tracking **
+ *
+ * A desired flow can be tracked - listed in ovn_desired_flow_table's
+ * tracked_flows.
+ *
+ * Tracked flows is initially empty, and stays empty after the first run of I-P
+ * engine when installed flows are initially populated. After that, flow
+ * changes are tracked when I-P engine incrementally computes flow changes.
+ * Tracked flows are then processed and removed completely in ofctrl_put.
+ * ("processed" means OpenFlow change messages are composed and sent/queued to
+ * OVS, which ensures flows in OVS is always in sync (eventually) with the
+ * installed flows table).
+ *
+ * In case of full recompute of I-P engine, tracked flows are not
+ * added/removed, and ofctrl_put will not rely on tracked flows. (It is I-P
+ * engine's responsibility to ensure the tracked flows are cleared before
+ * recompute).
+ *
+ * Tracked flows can be preserved across multiple I-P engine runs - if in some
+ * iterations ofctrl_put() is skipped. Tracked flows are cleared only when it
+ * is consumed or when flow recompute happens.
+ *
+ * The "change_tracked" member of desired flow table maintains the status of
+ * whether flow changes are tracked or not. It is always set to true when
+ * ofctrl_put is completed, and transition to false whenever
+ * ovn_desired_flow_table_clear is called.
+ *
+ * NOTE: A tracked flow is just a reference to a desired 

[ovs-dev] [PATCH ovn branch-20.03 13/16] ofctrl.c: Add a predictable resolution for conflicting flow actions.

2021-02-18 Thread Frode Nordahl
From: Dumitru Ceara 

Until now, in case the ACL configuration generates openflows that have
the same match but different actions, ovn-controller was using the
following approach:
1. If the flow being added contains conjunctive actions, merge its
   actions with the already existing flow.
2. Otherwise, if the flow is being added incrementally
   (update_installed_flows_by_track), don't install the new flow but
   instead keep the old one.
3. Otherwise, (update_installed_flows_by_compare), don't install the
   new flow but instead keep the old one.

Even though one can argue that having an ACL with a match that includes
the match of another ACL is a misconfiguration, it can happen that the
users provision OVN like this.  Depending on the order of reading and
installing the logical flows, the above operations can yield
unpredictable results, e.g., allow specific traffic but then after
ovn-controller is restarted (or a recompute happens) that specific
traffic starts being dropped.

A simple example of ACL configuration is:
ovn-nbctl acl-add ls to-lport 3 '(ip4.src==10.0.0.1 ||
ip4.src==10.0.0.2) && (ip4.dst == 10.0.0.3 || ip4.dst == 10.0.0.4)' allow
ovn-nbctl acl-add ls to-lport 3 'ip4.src==10.0.0.1' allow
ovn-nbctl acl-add ls to-lport 2 'arp' allow
ovn-nbctl acl-add ls to-lport 1 'ip4' drop

This is a pattern used by most CMSs:
- define a default deny policy.
- punch holes in the default deny policy based on user specific
  configurations.

Without this commit the behavior for traffic from 10.0.0.1 to 10.0.0.5
is unpredictable.  Depending on the order of operations traffic might be
dropped or allowed.

It's also quite hard to force the CMS to ensure that such match overlaps
never occur.

To address this issue we now ensure that all desired flows refering the
same installed flow are partially sorted in the following way:
- first all flows with action "allow".
- then all flows with action "drop".
- then a single flow with action "conjunction" (resulting from merging
  all flows with the same match and action conjunction).

This ensures that "allow" flows have precedence over "drop" flows which
in turn have precedence over "conjunction" flows.  Essentially less
restrictive flows are always preferred over more restrictive flows whenever a 
match
conflict happens.

CC: Daniel Alvarez 
Reported-at: https://bugzilla.redhat.com/1871931
Signed-off-by: Dumitru Ceara 
Acked-by: Mark Gray 
Signed-off-by: Han Zhou 
(cherry picked from commit 986b3d5e4ad6f05245d021ba699c957246294a22)
Signed-off-by: Frode Nordahl 
---
 controller/ofctrl.c |  74 +--
 tests/ovn.at| 214 
 2 files changed, 283 insertions(+), 5 deletions(-)

diff --git a/controller/ofctrl.c b/controller/ofctrl.c
index f06b68b78..60ce6f1c2 100644
--- a/controller/ofctrl.c
+++ b/controller/ofctrl.c
@@ -188,6 +188,14 @@ struct sb_flow_ref {
  * relationship is 1 to N. A link is added when a flow addition is processed.
  * A link is removed when a flow deletion is processed, the desired flow
  * table is cleared, or the installed flow table is cleared.
+ *
+ * To ensure predictable behavior, the list of desired flows is maintained
+ * partially sorted in the following way (from least restrictive to most
+ * restrictive wrt. match):
+ * - allow flows without action conjunction.
+ * - drop flows without action conjunction.
+ * - a single flow with action conjunction.
+ *
  * The first desired_flow in the list is the active one, the one that is
  * actually installed.
  */
@@ -795,6 +803,12 @@ ofctrl_recv(const struct ofp_header *oh, enum ofptype type)
 }
 }
 
+static bool
+flow_action_has_drop(const struct ovn_flow *f)
+{
+return f->ofpacts_len == 0;
+}
+
 static bool
 flow_action_has_conj(const struct ovn_flow *f)
 {
@@ -808,6 +822,33 @@ flow_action_has_conj(const struct ovn_flow *f)
 return false;
 }
 
+static bool
+flow_action_has_allow(const struct ovn_flow *f)
+{
+return !flow_action_has_drop(f) && !flow_action_has_conj(f);
+}
+
+/* Returns true if flow 'a' is preferred over flow 'b'. */
+static bool
+flow_is_preferred(const struct ovn_flow *a, const struct ovn_flow *b)
+{
+if (flow_action_has_allow(b)) {
+return false;
+}
+if (flow_action_has_allow(a)) {
+return true;
+}
+if (flow_action_has_drop(b)) {
+return false;
+}
+if (flow_action_has_drop(a)) {
+return true;
+}
+
+/* Flows 'a' and 'b' should never both have action conjunction. */
+OVS_NOT_REACHED();
+}
+
 /* Adds the desired flow to the list of desired flows that have same match
  * conditions as the installed flow.
  *
@@ -820,8 +861,18 @@ flow_action_has_conj(const struct ovn_flow *f)
 static bool
 link_installed_to_desired(struct installed_flow *i, struct desired_flow *d)
 {
+struct desired_flow *f;
+
+/* Find first 'f' such that 'd' is preferred over 'f'.  If no such desired
+ * flow exists then 'f' will point after the last element of 

[ovs-dev] [PATCH ovn branch-20.03 11/16] ofctrl.c: Simplify active desired flow selection.

2021-02-18 Thread Frode Nordahl
From: Dumitru Ceara 

Always consider the first "desired flow" in the list of flows that refer an
"installed flow" as the active flow.  This simplifies the logic of the flow
update code and is used in a further commit to implement a partial ordering
of desired flows within installed flows.

Signed-off-by: Dumitru Ceara 
Signed-off-by: Han Zhou 
(cherry picked from commit 107bb25029350bd0f7dfeeb0ef3053adbd504e3e)
Signed-off-by: Frode Nordahl 
---
 controller/ofctrl.c | 91 ++---
 1 file changed, 36 insertions(+), 55 deletions(-)

diff --git a/controller/ofctrl.c b/controller/ofctrl.c
index 843c7b2be..890ab4bb5 100644
--- a/controller/ofctrl.c
+++ b/controller/ofctrl.c
@@ -188,6 +188,8 @@ struct sb_flow_ref {
  * relationship is 1 to N. A link is added when a flow addition is processed.
  * A link is removed when a flow deletion is processed, the desired flow
  * table is cleared, or the installed flow table is cleared.
+ * The first desired_flow in the list is the active one, the one that is
+ * actually installed.
  */
 struct installed_flow {
 struct ovn_flow flow;
@@ -199,11 +201,6 @@ struct installed_flow {
  * installed flow, e.g. when there are conflict/duplicated ACLs that
  * generates same match conditions). */
 struct ovs_list desired_refs;
-
-/* The corresponding flow in desired table. It must be one of the flows in
- * desired_refs list.  If there are more than one flows in references list,
- * this is the one that is actually installed. */
-struct desired_flow *desired_flow;
 };
 
 typedef bool
@@ -231,6 +228,7 @@ static struct installed_flow *installed_flow_lookup(
 const struct ovn_flow *target);
 static void installed_flow_destroy(struct installed_flow *);
 static struct installed_flow *installed_flow_dup(struct desired_flow *);
+static struct desired_flow *installed_flow_get_active(struct installed_flow *);
 
 static uint32_t ovn_flow_match_hash(const struct ovn_flow *);
 static char *ovn_flow_to_string(const struct ovn_flow *);
@@ -796,24 +794,6 @@ ofctrl_recv(const struct ofp_header *oh, enum ofptype type)
 log_openflow_rl(, VLL_DBG, oh, "OpenFlow packet ignored");
 }
 }
-
-/* Returns true if a desired flow is active (the one currently installed
- * among the list of desired flows that are linked to the same installed
- * flow). */
-static inline bool
-desired_flow_is_active(struct desired_flow *d)
-{
-return (d->installed_flow && d->installed_flow->desired_flow == d);
-}
-
-/* Set a desired flow as the active one among the list of desired flows
- * that are linked to the same installed flow. */
-static inline void
-desired_flow_set_active(struct desired_flow *d)
-{
-ovs_assert(d->installed_flow);
-d->installed_flow->desired_flow = d;
-}
 
 static bool
 flow_action_has_conj(const struct ovn_flow *f)
@@ -831,27 +811,22 @@ flow_action_has_conj(const struct ovn_flow *f)
 /* Adds the desired flow to the list of desired flows that have same match
  * conditions as the installed flow.
  *
- * If the newly added desired flow is the first one in the list, it is also set
- * as the active one.
- *
  * It is caller's responsibility to make sure the link between the pair didn't
- * exist before. */
-static void
+ * exist before.
+ *
+ * Returns true if the newly added desired flow is selected to be the active
+ * one.
+ */
+static bool
 link_installed_to_desired(struct installed_flow *i, struct desired_flow *d)
 {
-ovs_assert(i->desired_flow != d);
-if (ovs_list_is_empty(>desired_refs)) {
-ovs_assert(!i->desired_flow);
-i->desired_flow = d;
-}
-ovs_list_insert(>desired_refs, >installed_ref_list_node);
 d->installed_flow = i;
+ovs_list_push_back(>desired_refs, >installed_ref_list_node);
+return installed_flow_get_active(i) == d;
 }
 
 /* Replaces 'old_desired' with 'new_desired' in the list of desired flows
  * that have same match conditions as the installed flow.
- *
- * If 'old_desired' was the active flow, 'new_desired' becomes the active one.
  */
 static void
 replace_installed_to_desired(struct installed_flow *i,
@@ -863,24 +838,22 @@ replace_installed_to_desired(struct installed_flow *i,
  _desired->installed_ref_list_node);
 old_desired->installed_flow = NULL;
 new_desired->installed_flow = i;
-if (i->desired_flow == old_desired) {
-i->desired_flow = new_desired;
-}
 }
 
-static void
+/* Removes the desired flow from the list of desired flows that have the same
+ * match conditions as the installed flow.
+ *
+ * Returns true if the desired flow was the previously active flow.
+ */
+static bool
 unlink_installed_to_desired(struct installed_flow *i, struct desired_flow *d)
 {
-ovs_assert(i && i->desired_flow && !ovs_list_is_empty(>desired_refs));
+struct desired_flow *old_active = installed_flow_get_active(i);
+
 ovs_assert(d && d->installed_flow == i);
 

[ovs-dev] [PATCH ovn branch-20.03 12/16] ofctrl.c: Always log the most recent flow changes.

2021-02-18 Thread Frode Nordahl
From: Dumitru Ceara 

Fixes: 6f0b1e02d9ab ("ofctrl: Incremental processing for flow installation by 
tracking.")
Signed-off-by: Dumitru Ceara 
Signed-off-by: Han Zhou 
(cherry picked from commit 33c15c145988daa6172928dc870f3a0225515f50)
Signed-off-by: Frode Nordahl 
---
 controller/ofctrl.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/controller/ofctrl.c b/controller/ofctrl.c
index 890ab4bb5..f06b68b78 100644
--- a/controller/ofctrl.c
+++ b/controller/ofctrl.c
@@ -1833,8 +1833,8 @@ update_installed_flows_by_track(struct 
ovn_desired_flow_table *flow_table,
  * installed flow, so update the OVS flow for the new
  * active flow (at least the cookie will be different,
  * even if the actions are the same). */
-ovn_flow_log(>flow, "updating installed (tracked)");
 installed_flow_mod(>flow, >flow, msgs);
+ovn_flow_log(>flow, "updating installed (tracked)");
 }
 }
 desired_flow_destroy(f);
@@ -1854,8 +1854,8 @@ update_installed_flows_by_track(struct 
ovn_desired_flow_table *flow_table,
 } else if (installed_flow_get_active(i) == f) {
 /* The installed flow is installed for f, but f has change
  * tracked, so it must have been modified. */
-ovn_flow_log(>flow, "updating installed (tracked)");
 installed_flow_mod(>flow, >flow, msgs);
+ovn_flow_log(>flow, "updating installed (tracked)");
 } else {
 /* Adding a new flow that conflicts with an existing installed
  * flow, so just add it to the link. */
-- 
2.30.0

___
dev mailing list
d...@openvswitch.org
https://mail.openvswitch.org/mailman/listinfo/ovs-dev


[ovs-dev] [PATCH ovn branch-20.03 08/16] ofctrl.c: Avoid repeatedly linking an installed flow and a desired flow.

2021-02-18 Thread Frode Nordahl
From: Han Zhou 

In update_installed_flows_by_compare() there are two loops. The first
loop iterates the installed flows and find its peer in desired flows to:

1. uninstall flows that are not needed anymore

2. update flows if needed

At the same time, it links the desired flow found for the installed flow
which also set the desired flow as the current active installed flow.

The second loop iterates the desired flows and find its peer in installed
flows to install missing flows. At the same time it will detect if there
are conflict desired flows matching same installed flow then just link
them.

However, currently in the second loop, it blindly link the desired flows to the
installed flows, without checking if it is already linked in the first loop.
Lucky enough, this won't cause any real problem so far, because when there are
conflict flows, the one found in the first loop will be set as active in the
installed_flow, and in the function link_installed_to_desired() checks if it is
already the active desired flow it just does nothing but return.  However, the
check in the link_installed_to_desired() is confusing because a desired_flow
may be linked to the installed_flow already but not the active flow, and the
check is insufficient. It should be rather an assertion and let the caller
ensure that a pair of desired_flow and installed_flow is never linked twice.

For the above reason, this patch does the following changes:

1. Removes the check in link_installed_to_desired() and convert it to an assert.

2. Before calling link_installed_to_desired() in the above mentioned loop,
   check if the desired flow is already installed.

Acked-by: Dumitru Ceara 
Signed-off-by: Han Zhou 
(cherry picked from commit 7cab7bd1268ba67429954da4f73de91090acf779)
Signed-off-by: Frode Nordahl 
---
 controller/ofctrl.c | 19 ++-
 1 file changed, 14 insertions(+), 5 deletions(-)

diff --git a/controller/ofctrl.c b/controller/ofctrl.c
index 41495c41f..70ec3e82b 100644
--- a/controller/ofctrl.c
+++ b/controller/ofctrl.c
@@ -806,13 +806,18 @@ desired_flow_set_active(struct desired_flow *d)
 d->installed_flow->desired_flow = d;
 }
 
+/* Adds the desired flow to the list of desired flows that have same match
+ * conditions as the installed flow.
+ *
+ * If the newly added desired flow is the first one in the list, it is also set
+ * as the active one.
+ *
+ * It is caller's responsibility to make sure the link between the pair didn't
+ * exist before. */
 static void
 link_installed_to_desired(struct installed_flow *i, struct desired_flow *d)
 {
-if (i->desired_flow == d) {
-return;
-}
-
+ovs_assert(i->desired_flow != d);
 if (ovs_list_is_empty(>desired_refs)) {
 ovs_assert(!i->desired_flow);
 i->desired_flow = d;
@@ -1644,8 +1649,12 @@ update_installed_flows_by_compare(struct 
ovn_desired_flow_table *flow_table,
 /* Copy 'd' from 'flow_table' to installed_flows. */
 i = installed_flow_dup(d);
 hmap_insert(_flows, >match_hmap_node, i->flow.hash);
+link_installed_to_desired(i, d);
+} else if (!d->installed_flow) {
+/* This is a desired_flow that conflicts with one installed
+ * previously but not linked yet. */
+link_installed_to_desired(i, d);
 }
-link_installed_to_desired(i, d);
 }
 }
 
-- 
2.30.0

___
dev mailing list
d...@openvswitch.org
https://mail.openvswitch.org/mailman/listinfo/ovs-dev


[ovs-dev] [PATCH ovn branch-20.03 02/16] Revert "Manage ARP process locally in a DVR scenario"

2021-02-18 Thread Frode Nordahl
From: Lorenzo Bianconi 

This reverts commit c0bf32d72f8b893bbe3cb64912b0fd259d71555f.

Signed-off-by: Lorenzo Bianconi 
Signed-off-by: Han Zhou 
(cherry picked from commit d9ed450713eda62af1bec5009694b2d206c9f435)
Signed-off-by: Frode Nordahl 
---
 northd/ovn-northd.8.xml | 37 ++--
 northd/ovn-northd.c | 53 +
 tests/ovn.at| 14 ---
 3 files changed, 3 insertions(+), 101 deletions(-)

diff --git a/northd/ovn-northd.8.xml b/northd/ovn-northd.8.xml
index f5a14d26e..4b8264bb4 100644
--- a/northd/ovn-northd.8.xml
+++ b/northd/ovn-northd.8.xml
@@ -2484,46 +2484,13 @@ output;
 
   
 
-  
-
-  For distributed logical routers where one of the logical router ports
-  specifies a redirect-chassis, a priority-400 logical
-  flow for each dnat_and_snat NAT rules configured.
-  These flows will allow to properly forward traffic to the external
-  connections if available and avoid sending it through the tunnel.
-  Assuming the following NAT rule has been configured:
-
-
-
-external_ip = A;
-external_mac = B;
-logical_ip = C;
-
-
-
-  the following action will be applied:
-
-
-
-ip.ttl--;
-reg0 = ip.dst;
-reg1 = A;
-eth.src = B;
-outport = router-port;
-next;
-
-
-  
-
   
 
   IPv4 routing table.  For each route to IPv4 network N with
   netmask M, on router port P with IP address
   A and Ethernet
   address E, a logical flow with match ip4.dst ==
-  N/M, whose priority is 400
-  + the number of 1-bits in M if the router port is not a
-  distributed gateway port, else the priority is the number of
+  N/M, whose priority is the number of
   1-bits in M, has the following actions:
 
 
@@ -2922,7 +2889,7 @@ icmp4 {
 
   
 For each NAT rule in the OVN Northbound database that can
-be handled in a distributed manner, a priority-200 logical
+be handled in a distributed manner, a priority-100 logical
 flow with match ip4.src == B 
 outport == GW, where GW is
 the logical router distributed gateway port, with actions
diff --git a/northd/ovn-northd.c b/northd/ovn-northd.c
index 62911986b..2453dca08 100644
--- a/northd/ovn-northd.c
+++ b/northd/ovn-northd.c
@@ -7060,8 +7060,6 @@ build_routing_policy_flow(struct hmap *lflows, struct 
ovn_datapath *od,
 ds_destroy();
 }
 
-/* default logical flow prioriry for distributed routes */
-#define DROUTE_PRIO 400
 struct parsed_route {
 struct ovs_list list_node;
 struct v46_ip prefix;
@@ -7449,40 +7447,6 @@ build_ecmp_route_flow(struct hmap *lflows, struct 
ovn_datapath *od,
 ds_destroy();
 }
 
-static void
-add_distributed_routes(struct hmap *lflows, struct ovn_datapath *od)
-{
-struct ds actions = DS_EMPTY_INITIALIZER;
-struct ds match = DS_EMPTY_INITIALIZER;
-
-for (size_t i = 0; i < od->nbr->n_nat; i++) {
-const struct nbrec_nat *nat = od->nbr->nat[i];
-
-if (strcmp(nat->type, "dnat_and_snat") ||
-!nat->external_mac) {
-continue;
-}
-
-bool is_ipv4 = strchr(nat->logical_ip, '.') ? true : false;
-ds_put_format(, "ip%s.src == %s && is_chassis_resident(\"%s\")",
-  is_ipv4 ? "4" : "6", nat->logical_ip,
-  nat->logical_port);
-char *prefix = is_ipv4 ? "" : "xx";
-ds_put_format(, "outport = %s; eth.src = %s; "
-  "%sreg0 = ip%s.dst; %sreg1 = %s; next;",
-  od->l3dgw_port->json_key, nat->external_mac,
-  prefix, is_ipv4 ? "4" : "6",
-  prefix, nat->external_ip);
-ovn_lflow_add(lflows, od, S_ROUTER_IN_IP_ROUTING, DROUTE_PRIO,
-  ds_cstr(), ds_cstr());
-ds_clear();
-ds_clear();
-}
-
-ds_destroy();
-ds_destroy();
-}
-
 static void
 add_route(struct hmap *lflows, const struct ovn_port *op,
   const char *lrp_addr_s, const char *network_s, int plen,
@@ -7504,12 +7468,6 @@ add_route(struct hmap *lflows, const struct ovn_port *op,
 }
 build_route_match(op_inport, network_s, plen, is_src_route, is_ipv4,
   , );
-/* traffic for internal IPs of logical switch ports must be sent to
- * the gw controller through the overlay tunnels
- */
-if (op->nbrp && !op->nbrp->n_gateway_chassis) {
-priority += DROUTE_PRIO;
-}
 
 struct ds actions = DS_EMPTY_INITIALIZER;
 ds_put_format(, "ip.ttl--; "REG_ECMP_GROUP_ID" = 0; %sreg0 = ",
@@ -9119,7 +9077,7 @@ build_lrouter_flows(struct hmap *datapaths, struct hmap 
*ports,
   nat->logical_ip,
   od->l3dgw_port->json_key);
 ovn_lflow_add_with_hint(lflows, od, S_ROUTER_IN_GW_REDIRECT,

[ovs-dev] [PATCH ovn branch-20.03 09/16] ofctrl.c: Only merge actions for conjunctive flows.

2021-02-18 Thread Frode Nordahl
From: Dumitru Ceara 

In ofctrl_add_or_append_flow() when merging flow actions make sure we only
do that for conjunctive flows.  All other actions can not be merged with
action "conjunction".

CC: Mark Michelson 
Fixes: e659bab31a91 ("Combine conjunctions with identical matches into one 
flow.")
Signed-off-by: Dumitru Ceara 
Signed-off-by: Han Zhou 
(cherry picked from commit dadae4f800ccb1f2759378f0bd804dd002e31605)
Signed-off-by: Frode Nordahl 
---
 controller/ofctrl.c | 124 +++-
 1 file changed, 99 insertions(+), 25 deletions(-)

diff --git a/controller/ofctrl.c b/controller/ofctrl.c
index 70ec3e82b..5322d5148 100644
--- a/controller/ofctrl.c
+++ b/controller/ofctrl.c
@@ -206,6 +206,9 @@ struct installed_flow {
 struct desired_flow *desired_flow;
 };
 
+typedef bool
+(*desired_flow_match_cb)(const struct desired_flow *candidate,
+ const void *arg);
 static struct desired_flow *desired_flow_alloc(
 uint8_t table_id,
 uint16_t priority,
@@ -213,9 +216,15 @@ static struct desired_flow *desired_flow_alloc(
 const struct match *match,
 const struct ofpbuf *actions);
 static struct desired_flow *desired_flow_lookup(
+struct ovn_desired_flow_table *,
+const struct ovn_flow *target);
+static struct desired_flow *desired_flow_lookup_check_uuid(
 struct ovn_desired_flow_table *,
 const struct ovn_flow *target,
-const struct uuid *sb_uuid);
+const struct uuid *);
+static struct desired_flow *desired_flow_lookup_conjunctive(
+struct ovn_desired_flow_table *,
+const struct ovn_flow *target);
 static void desired_flow_destroy(struct desired_flow *);
 
 static struct installed_flow *installed_flow_lookup(
@@ -806,6 +815,19 @@ desired_flow_set_active(struct desired_flow *d)
 d->installed_flow->desired_flow = d;
 }
 
+static bool
+flow_action_has_conj(const struct ovn_flow *f)
+{
+const struct ofpact *a = NULL;
+
+OFPACT_FOR_EACH (a, f->ofpacts, f->ofpacts_len) {
+if (a->type == OFPACT_CONJUNCTION) {
+return true;
+}
+}
+return false;
+}
+
 /* Adds the desired flow to the list of desired flows that have same match
  * conditions as the installed flow.
  *
@@ -962,7 +984,7 @@ ofctrl_check_and_add_flow(struct ovn_desired_flow_table 
*flow_table,
 struct desired_flow *f = desired_flow_alloc(table_id, priority, cookie,
 match, actions);
 
-if (desired_flow_lookup(flow_table, >flow, sb_uuid)) {
+if (desired_flow_lookup_check_uuid(flow_table, >flow, sb_uuid)) {
 if (log_duplicate_flow) {
 static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(5, 5);
 if (!VLOG_DROP_DBG()) {
@@ -1002,14 +1024,15 @@ ofctrl_add_or_append_flow(struct ovn_desired_flow_table 
*desired_flows,
   const struct ofpbuf *actions,
   const struct uuid *sb_uuid)
 {
-struct desired_flow *f = desired_flow_alloc(table_id, priority, cookie,
-match, actions);
-
 struct desired_flow *existing;
-existing = desired_flow_lookup(desired_flows, >flow, NULL);
+struct desired_flow *f;
+
+f = desired_flow_alloc(table_id, priority, cookie, match, actions);
+existing = desired_flow_lookup_conjunctive(desired_flows, >flow);
 if (existing) {
-/* There's already a flow with this particular match. Append the
- * action to that flow rather than adding a new flow
+/* There's already a flow with this particular match and action
+ * 'conjunction'. Append the action to that flow rather than
+ * adding a new flow.
  */
 uint64_t compound_stub[64 / 8];
 struct ofpbuf compound;
@@ -1248,15 +1271,11 @@ installed_flow_dup(struct desired_flow *src)
 return dst;
 }
 
-/* Finds and returns a desired_flow in 'flow_table' whose key is identical to
- * 'target''s key, or NULL if there is none.
- *
- * If sb_uuid is not NULL, the function will also check if the found flow is
- * referenced by the sb_uuid. */
 static struct desired_flow *
-desired_flow_lookup(struct ovn_desired_flow_table *flow_table,
-const struct ovn_flow *target,
-const struct uuid *sb_uuid)
+desired_flow_lookup__(struct ovn_desired_flow_table *flow_table,
+  const struct ovn_flow *target,
+  desired_flow_match_cb match_cb,
+  const void *arg)
 {
 struct desired_flow *d;
 HMAP_FOR_EACH_WITH_HASH (d, match_hmap_node, target->hash,
@@ -1265,20 +1284,76 @@ desired_flow_lookup(struct ovn_desired_flow_table 
*flow_table,
 if (f->table_id == target->table_id
 && f->priority == target->priority
 && minimatch_equal(>match, >match)) {
-if (!sb_uuid) {
+
+if (!match_cb || match_cb(d, arg)) {
 return d;
 

[ovs-dev] [PATCH ovn branch-20.03 10/16] ofctrl.c: Do not change flow ordering when merging opposite changes.

2021-02-18 Thread Frode Nordahl
From: Dumitru Ceara 

Instead of removing the old desired flow from the list and inserting the new
one at the end we now directly replace the old flow with the new one while
maintaining the same ordering.

For now order of the flows is not relevant but further commits require
maintaining the order of desired flows.

Signed-off-by: Dumitru Ceara 
Signed-off-by: Han Zhou 
(cherry picked from commit e49ce9a33f38f29c44e3c30afcc189b5f6a9ef8e)
Signed-off-by: Frode Nordahl 
---
 controller/ofctrl.c | 28 +---
 1 file changed, 21 insertions(+), 7 deletions(-)

diff --git a/controller/ofctrl.c b/controller/ofctrl.c
index 5322d5148..843c7b2be 100644
--- a/controller/ofctrl.c
+++ b/controller/ofctrl.c
@@ -848,6 +848,26 @@ link_installed_to_desired(struct installed_flow *i, struct 
desired_flow *d)
 d->installed_flow = i;
 }
 
+/* Replaces 'old_desired' with 'new_desired' in the list of desired flows
+ * that have same match conditions as the installed flow.
+ *
+ * If 'old_desired' was the active flow, 'new_desired' becomes the active one.
+ */
+static void
+replace_installed_to_desired(struct installed_flow *i,
+ struct desired_flow *old_desired,
+ struct desired_flow *new_desired)
+{
+ovs_assert(old_desired->installed_flow == i);
+ovs_list_replace(_desired->installed_ref_list_node,
+ _desired->installed_ref_list_node);
+old_desired->installed_flow = NULL;
+new_desired->installed_flow = i;
+if (i->desired_flow == old_desired) {
+i->desired_flow = new_desired;
+}
+}
+
 static void
 unlink_installed_to_desired(struct installed_flow *i, struct desired_flow *d)
 {
@@ -1781,21 +1801,15 @@ merge_tracked_flows(struct ovn_desired_flow_table 
*flow_table)
  * removed during track_flow_add_or_modify. */
 ovs_assert(del_f->installed_flow);
 
-bool del_f_was_active = desired_flow_is_active(del_f);
 if (!f->installed_flow) {
 /* f is not installed yet. */
-struct installed_flow *i = del_f->installed_flow;
-unlink_installed_to_desired(i, del_f);
-link_installed_to_desired(i, f);
+replace_installed_to_desired(del_f->installed_flow, del_f, f);
 } else {
 /* f has been installed before, and now was updated to exact
  * the same flow as del_f. */
 ovs_assert(f->installed_flow == del_f->installed_flow);
 unlink_installed_to_desired(del_f->installed_flow, del_f);
 }
-if (del_f_was_active) {
-desired_flow_set_active(f);
-}
 hmap_remove(_flows, _f->match_hmap_node);
 ovs_list_remove(_f->track_list_node);
 desired_flow_destroy(del_f);
-- 
2.30.0

___
dev mailing list
d...@openvswitch.org
https://mail.openvswitch.org/mailman/listinfo/ovs-dev


[ovs-dev] [PATCH ovn branch-20.03 01/16] ovn-ctl: Handle cluster db upgrades for run_(nb/sb)_ovsdb

2021-02-18 Thread Frode Nordahl
From: Numan Siddique 

when ovn-ctl run_(nb_sb)_ovsdb is called, the ovsdb-server is started without
passing --detach and --monoitor and the process is exec'd.

For cluster mode, upgrade_cluster is never called and hence the dbs are not 
upraded
to new schema. CMS has to handle the db upgrade separately.

This patch handles the db upgrade by starting ovsdb-server in background and 
then
waits on ovsdb-server to complete.

Reported-at: https://bugzilla.redhat.com/show_bug.cgi?id=1868392
Acked-by: Mark Michelson 
Signed-off-by: Numan Siddique 
(cherry picked from commit 67e2f386cc838d0b0f9b4b5da7fe611e1113b70c)
Signed-off-by: Frode Nordahl 
---
 utilities/ovn-ctl | 20 +++-
 1 file changed, 19 insertions(+), 1 deletion(-)

diff --git a/utilities/ovn-ctl b/utilities/ovn-ctl
index c7cb42bc1..7285c0533 100755
--- a/utilities/ovn-ctl
+++ b/utilities/ovn-ctl
@@ -284,7 +284,21 @@ $cluster_remote_port
 set "$@" --sync-from=`cat $active_conf_file`
 fi
 
-"$@" "$file"
+local run_ovsdb_in_bg="no"
+local process_id=
+if test X$detach = Xno && test $mode = cluster && test -z 
"$cluster_remote_addr" ; then
+# When detach is no (for run_nb_ovsdb/run_sb_ovsdb commands)
+# we want to run ovsdb-server in background rather than running it in
+# foreground so that the OVN dbs are upgraded for the cluster mode.
+# Otherwise, CMS has to take the responsibility of upgrading the dbs.
+# Note: We run only the ovsdb-server in backgroud which created the
+# cluster (i.e cluster_remote_addr is not set.).
+run_ovsdb_in_bg="yes"
+"$@" $file &
+process_id=$!
+else
+start_wrapped_daemon "$wrapper" ovsdb-$db "" "$@" "$file"
+fi
 
 # Initialize the database if it's running standalone,
 # active-passive, or is the first server in a cluster.
@@ -295,6 +309,10 @@ $cluster_remote_port
 if test $mode = cluster; then
 upgrade_cluster "$schema" "unix:$sock"
 fi
+
+if test $run_ovsdb_in_bg = yes; then
+wait $process_id
+fi
 }
 
 start_nb_ovsdb() {
-- 
2.30.0

___
dev mailing list
d...@openvswitch.org
https://mail.openvswitch.org/mailman/listinfo/ovs-dev


[ovs-dev] [PATCH ovn branch-20.03 06/16] ofctrl.c: Merge opposite changes of tracked flows before installing.

2021-02-18 Thread Frode Nordahl
From: Han Zhou 

This patch optimizes the previous patch that incrementally processes
flow installation by merging the "add-after-delete" flow changes as
much as possible to avoid unnecessary OpenFlow updates.

Acked-by: Mark Michelson 
Signed-off-by: Han Zhou 
(cherry picked from commit f4e508dd7a6cfbfc2e3250a8c11a8d0fdc1dfdd0)
Signed-off-by: Frode Nordahl 
---
 controller/ofctrl.c | 74 +
 1 file changed, 74 insertions(+)

diff --git a/controller/ofctrl.c b/controller/ofctrl.c
index 3ff8604b1..b526c68f4 100644
--- a/controller/ofctrl.c
+++ b/controller/ofctrl.c
@@ -1631,10 +1631,84 @@ update_installed_flows_by_compare(struct 
ovn_desired_flow_table *flow_table,
 }
 }
 
+/* Finds and returns a desired_flow in 'deleted_flows' that is exactly the
+ * same as 'target', including cookie and actions.
+ */
+static struct desired_flow *
+deleted_flow_lookup(struct hmap *deleted_flows, struct ovn_flow *target)
+{
+struct desired_flow *d;
+HMAP_FOR_EACH_WITH_HASH (d, match_hmap_node, target->hash,
+ deleted_flows) {
+struct ovn_flow *f = >flow;
+if (f->table_id == target->table_id
+&& f->priority == target->priority
+&& minimatch_equal(>match, >match)
+&& f->cookie == target->cookie
+&& ofpacts_equal(f->ofpacts, f->ofpacts_len, target->ofpacts,
+ target->ofpacts_len)) {
+return d;
+}
+}
+return NULL;
+}
+
+/* This function scans the tracked flow changes in the order and merges "add"
+ * or "update" after "deleted" operations for exactly same flow (priority,
+ * table, match, action and cookie), to avoid unnecessary OF messages being
+ * sent to OVS. */
+static void
+merge_tracked_flows(struct ovn_desired_flow_table *flow_table)
+{
+struct hmap deleted_flows = HMAP_INITIALIZER(_flows);
+struct desired_flow *f, *next;
+LIST_FOR_EACH_SAFE (f, next, track_list_node,
+_table->tracked_flows) {
+if (f->is_deleted) {
+/* reuse f->match_hmap_node field since it is already removed from
+ * the desired flow table's match index. */
+hmap_insert(_flows, >match_hmap_node,
+f->flow.hash);
+} else {
+struct desired_flow *del_f = deleted_flow_lookup(_flows,
+ >flow);
+if (!del_f) {
+continue;
+}
+
+/* del_f must have been installed, otherwise it should have been
+ * removed during track_flow_add_or_modify. */
+ovs_assert(del_f->installed_flow);
+if (!f->installed_flow) {
+/* f is not installed yet. */
+struct installed_flow *i = del_f->installed_flow;
+unlink_installed_to_desired(i, del_f);
+link_installed_to_desired(i, f);
+} else {
+/* f has been installed before, and now was updated to exact
+ * the same flow as del_f. */
+ovs_assert(f->installed_flow == del_f->installed_flow);
+unlink_installed_to_desired(del_f->installed_flow, del_f);
+}
+hmap_remove(_flows, _f->match_hmap_node);
+ovs_list_remove(_f->track_list_node);
+desired_flow_destroy(del_f);
+
+ovs_list_remove(>track_list_node);
+ovs_list_init(>track_list_node);
+}
+}
+HMAP_FOR_EACH_SAFE (f, next, match_hmap_node, _flows) {
+hmap_remove(_flows, >match_hmap_node);
+}
+hmap_destroy(_flows);
+}
+
 static void
 update_installed_flows_by_track(struct ovn_desired_flow_table *flow_table,
 struct ovs_list *msgs)
 {
+merge_tracked_flows(flow_table);
 struct desired_flow *f, *f_next;
 LIST_FOR_EACH_SAFE (f, f_next, track_list_node,
 _table->tracked_flows) {
-- 
2.30.0

___
dev mailing list
d...@openvswitch.org
https://mail.openvswitch.org/mailman/listinfo/ovs-dev


[ovs-dev] [PATCH ovn branch-20.03 03/16] ofctrl.c: Maintain references between installed flows and desired flows.

2021-02-18 Thread Frode Nordahl
From: Han Zhou 

Currently there is no link maintained between installed flows and desired
flows. This patch maintains the mapping between them, which will be useful
for a future patch that incrementally processes the flow installation without
having to do the full comparison between them.

This patch also refactors the struct ovn_flow with two different wrapper
types: desired_flow and installed_flow, and the related static functions,
to make the code easier to read and avoid misuses of the struct.

Acked-by: Mark Michelson 
Signed-off-by: Han Zhou 
(cherry picked from commit 354d3853d40cbce89a434632f67daed7fc992d8b)
Signed-off-by: Frode Nordahl 
---
 controller/ofctrl.c | 428 ++--
 1 file changed, 294 insertions(+), 134 deletions(-)

diff --git a/controller/ofctrl.c b/controller/ofctrl.c
index 2a337e309..0d6326fc3 100644
--- a/controller/ofctrl.c
+++ b/controller/ofctrl.c
@@ -51,7 +51,27 @@
 
 VLOG_DEFINE_THIS_MODULE(ofctrl);
 
-/* An OpenFlow flow.
+/* An OpenFlow flow. */
+struct ovn_flow {
+/* Key. */
+uint8_t table_id;
+uint16_t priority;
+struct minimatch match;
+
+/* Hash. */
+uint32_t hash;
+
+/* Data. */
+struct ofpact *ofpacts;
+size_t ofpacts_len;
+uint64_t cookie;
+};
+
+/* A desired flow, in struct ovn_desired_flow_table, calculated by the
+ * incremental processing engine.
+ * - They are added/removed incrementally when I-P engine is able to process
+ *   the changes incrementally, or
+ * - Completely cleared and recomputed by I-P engine when recompute happens.
  *
  * Links are maintained between desired flows and SB data. The relationship
  * is M to N. The struct sb_flow_ref is used to link a pair of desired flow
@@ -82,52 +102,92 @@ VLOG_DEFINE_THIS_MODULE(ofctrl);
  * The links are updated whenever there is a change in desired flows, which is
  * usually triggered by a SB data change in I-P engine.
  */
-struct ovn_flow {
+struct desired_flow {
+struct ovn_flow flow;
 struct hmap_node match_hmap_node; /* For match based hashing. */
 struct ovs_list list_node; /* For handling lists of flows. */
-struct ovs_list references; /* A list of struct sb_flow_ref nodes, which
-   references this flow. (There are cases
-   that multiple SB entities share the same
-   desired OpenFlow flow, e.g. when
-   conjunction is used.) */
 
-/* Key. */
-uint8_t table_id;
-uint16_t priority;
-struct minimatch match;
+/* A list of struct sb_flow_ref nodes, which references this flow. (There
+ * are cases that multiple SB entities share the same desired OpenFlow
+ * flow, e.g. when conjunction is used.) */
+struct ovs_list references;
 
-/* Data. */
-struct ofpact *ofpacts;
-size_t ofpacts_len;
-uint64_t cookie;
+/* The corresponding flow in installed table. */
+struct installed_flow *installed_flow;
+
+/* Node in installed_flow.desired_refs list. */
+struct ovs_list installed_ref_list_node;
 };
 
 struct sb_to_flow {
 struct hmap_node hmap_node; /* Node in
ovn_desired_flow_table.uuid_flow_table. */
 struct uuid sb_uuid;
-struct ovs_list flows; /* A list of struct sb_flow_ref nodes that are
-  referenced by the sb_uuid. */
+struct ovs_list flows; /* A list of struct sb_flow_ref nodes that
+  are referenced by the sb_uuid. */
 };
 
 struct sb_flow_ref {
-struct ovs_list sb_list; /* List node in ovn_flow.references. */
-struct ovs_list flow_list; /* List node in sb_to_flow.ovn_flows. */
-struct ovn_flow *flow;
+struct ovs_list sb_list; /* List node in desired_flow.references. */
+struct ovs_list flow_list; /* List node in sb_to_flow.desired_flows. */
+struct desired_flow *flow;
 struct uuid sb_uuid;
 };
 
-static struct ovn_flow *ovn_flow_alloc(uint8_t table_id, uint16_t priority,
-   uint64_t cookie,
-   const struct match *match,
-   const struct ofpbuf *actions);
+/* A installed flow, in static variable installed_flows.
+ *
+ * Installed flows are updated in ofctrl_put for maintaining the flow
+ * installation to OVS. They are updated according to desired flows: either by
+ * processing the tracked desired flow changes, or by comparing desired flows
+ * with currently installed flows when tracked desired flows changes are not
+ * available.
+ *
+ * In addition, when ofctrl state machine enters S_CLEAR, the installed flows
+ * will be cleared. (This happens in initialization phase and also when
+ * ovs-vswitchd is disconnected/reconnected).
+ *
+ * Links are maintained between installed flows and desired flows. The
+ * relationship is 1 to N. A link is added when a flow addition is 

[ovs-dev] [PATCH ovn branch-20.03 04/16] ofctrl.c: Refactor - move openflow msg construction to functions.

2021-02-18 Thread Frode Nordahl
From: Han Zhou 

These functions will be reused in multiple places in a future patch.

Acked-by: Mark Michelson 
Signed-off-by: Han Zhou 
(cherry picked from commit 23063cf4178c05f5d6b3e4ec6d323ccc88df6101)
Signed-off-by: Frode Nordahl 
---
 controller/ofctrl.c | 103 ++--
 1 file changed, 60 insertions(+), 43 deletions(-)

diff --git a/controller/ofctrl.c b/controller/ofctrl.c
index 0d6326fc3..6de14ac9d 100644
--- a/controller/ofctrl.c
+++ b/controller/ofctrl.c
@@ -1419,6 +1419,63 @@ add_meter(struct ovn_extend_table_info *m_desired,
 free(mm.meter.bands);
 }
 
+static void
+installed_flow_add(struct ovn_flow *d, struct ovs_list *msgs)
+{
+/* Send flow_mod to add flow. */
+struct ofputil_flow_mod fm = {
+.match = d->match,
+.priority = d->priority,
+.table_id = d->table_id,
+.ofpacts = d->ofpacts,
+.ofpacts_len = d->ofpacts_len,
+.new_cookie = htonll(d->cookie),
+.command = OFPFC_ADD,
+};
+add_flow_mod(, msgs);
+}
+
+static void
+installed_flow_mod(struct ovn_flow *i, struct ovn_flow *d,
+   struct ovs_list *msgs)
+{
+/* Update actions in installed flow. */
+struct ofputil_flow_mod fm = {
+.match = i->match,
+.priority = i->priority,
+.table_id = i->table_id,
+.ofpacts = d->ofpacts,
+.ofpacts_len = d->ofpacts_len,
+.command = OFPFC_MODIFY_STRICT,
+};
+/* Update cookie if it is changed. */
+if (i->cookie != d->cookie) {
+fm.modify_cookie = true;
+fm.new_cookie = htonll(d->cookie);
+/* Use OFPFC_ADD so that cookie can be updated. */
+fm.command = OFPFC_ADD;
+}
+add_flow_mod(, msgs);
+
+/* Replace 'i''s actions and cookie by 'd''s. */
+free(i->ofpacts);
+i->ofpacts = xmemdup(d->ofpacts, d->ofpacts_len);
+i->ofpacts_len = d->ofpacts_len;
+i->cookie = d->cookie;
+}
+
+static void
+installed_flow_del(struct ovn_flow *i, struct ovs_list *msgs)
+{
+struct ofputil_flow_mod fm = {
+.match = i->match,
+.priority = i->priority,
+.table_id = i->table_id,
+.command = OFPFC_DELETE_STRICT,
+};
+add_flow_mod(, msgs);
+}
+
 /* The flow table can be updated if the connection to the switch is up and
  * in the correct state and not backlogged with existing flow_mods.  (Our
  * criteria for being backlogged appear very conservative, but the socket
@@ -1544,46 +1601,16 @@ ofctrl_put(struct ovn_desired_flow_table *flow_table,
 if (!d) {
 /* Installed flow is no longer desirable.  Delete it from the
  * switch and from installed_flows. */
-struct ofputil_flow_mod fm = {
-.match = i->flow.match,
-.priority = i->flow.priority,
-.table_id = i->flow.table_id,
-.command = OFPFC_DELETE_STRICT,
-};
-add_flow_mod(, );
+installed_flow_del(>flow, );
 ovn_flow_log(>flow, "removing installed");
-
 hmap_remove(_flows, >match_hmap_node);
 installed_flow_destroy(i);
 } else {
 if (!ofpacts_equal(i->flow.ofpacts, i->flow.ofpacts_len,
d->flow.ofpacts, d->flow.ofpacts_len) ||
 i->flow.cookie != d->flow.cookie) {
-/* Update actions in installed flow. */
-struct ofputil_flow_mod fm = {
-.match = i->flow.match,
-.priority = i->flow.priority,
-.table_id = i->flow.table_id,
-.ofpacts = d->flow.ofpacts,
-.ofpacts_len = d->flow.ofpacts_len,
-.command = OFPFC_MODIFY_STRICT,
-};
-/* Update cookie if it is changed. */
-if (i->flow.cookie != d->flow.cookie) {
-fm.modify_cookie = true;
-fm.new_cookie = htonll(d->flow.cookie);
-/* Use OFPFC_ADD so that cookie can be updated. */
-fm.command = OFPFC_ADD,
-i->flow.cookie = d->flow.cookie;
-}
-add_flow_mod(, );
 ovn_flow_log(>flow, "updating installed");
-
-/* Replace 'i''s actions by 'd''s. */
-free(i->flow.ofpacts);
-i->flow.ofpacts = xmemdup(d->flow.ofpacts,
-  d->flow.ofpacts_len);
-i->flow.ofpacts_len = d->flow.ofpacts_len;
+installed_flow_mod(>flow, >flow, );
 }
 link_installed_to_desired(i, d);
 
@@ -1596,17 +1623,7 @@ ofctrl_put(struct ovn_desired_flow_table *flow_table,
 HMAP_FOR_EACH (d, match_hmap_node, _table->match_flow_table) {
 i = installed_flow_lookup(>flow);
 if (!i) {
-/* Send flow_mod to add flow. */
-struct ofputil_flow_mod 

[ovs-dev] [PATCH ovn branch-20.03 00/16] Backport rollup

2021-02-18 Thread Frode Nordahl
Hello all,

In Ubuntu we have backported a set of fixes to our OVN 20.06 and OVN
20.03 packages.  In preparing for new point releases for OVN 20.06
and OVN 20.03, we would very much like to add these patches to the
upstream branches.

The issues solved for OVN 20.03 with these patches are:

  * Fix for incorrect ARP processing with DVR enabled (LP: #1905933)[0]
  * Fix for upgrading database schema of clustered databases on package
upgrade (LP: #1907081)[1]
  * Fixes for predictable resolution for conflicting flow actions.
(LP: #1906922)[2]

We are cognizant of the large number of patches required to cleanly
backport the conflicting flow actions fixes, and have verified the end
result thouroughly. From our experience these fixes are required to use
OVN with OpenStack in a meaningful way, for example with k8s on top of
OpenStack.

0: https://bugs.launchpad.net/bugs/1905933
1: https://bugs.launchpad.net/bugs/1907081
2: https://bugs.launchpad.net/bugs/1906922

Dumitru Ceara (8):
  ofctrl.c: Only merge actions for conjunctive flows.
  ofctrl.c: Do not change flow ordering when merging opposite changes.
  ofctrl.c: Simplify active desired flow selection.
  ofctrl.c: Always log the most recent flow changes.
  ofctrl.c: Add a predictable resolution for conflicting flow actions.
  ovn.at: Make some of the tests more predictable.
  tests: Add ofctl_strip_all() to filter OVS flow outputs.
  tests: Fix test "ovn -- Superseding ACLs with conjunction".

Han Zhou (6):
  ofctrl.c: Maintain references between installed flows and desired
flows.
  ofctrl.c: Refactor - move openflow msg construction to functions.
  ofctrl: Incremental processing for flow installation by tracking.
  ofctrl.c: Merge opposite changes of tracked flows before installing.
  ofctrl.c: Fix duplicated flow handling in I-P while merging opposite
changes.
  ofctrl.c: Avoid repeatedly linking an installed flow and a desired
flow.

Lorenzo Bianconi (1):
  Revert "Manage ARP process locally in a DVR scenario"

Numan Siddique (1):
  ovn-ctl: Handle cluster db upgrades for run_(nb/sb)_ovsdb

 controller/ofctrl.c | 966 
 controller/ofctrl.h |   6 +-
 northd/ovn-northd.8.xml |  37 +-
 northd/ovn-northd.c |  53 +--
 tests/ofproto-macros.at |  23 +-
 tests/ovn.at| 342 +-
 utilities/ovn-ctl   |  20 +-
 7 files changed, 1159 insertions(+), 288 deletions(-)

-- 
2.30.0

___
dev mailing list
d...@openvswitch.org
https://mail.openvswitch.org/mailman/listinfo/ovs-dev


[ovs-dev] [PATCH ovn branch-20.06 15/15] tests: Fix test "ovn -- Superseding ACLs with conjunction".

2021-02-18 Thread Dumitru Ceara
The test was checking the output of "ovs-ofctl dump-flows" without
taking into account that some fields don't have predictable values,
e.g., hard_age.

Instead, use ofctl_strip_all().

Fixes: 986b3d5e4ad6 ("ofctrl.c: Add a predictable resolution for conflicting 
flow actions.")
Reported-by: Numan Siddique 
Signed-off-by: Dumitru Ceara 
Signed-off-by: Numan Siddique 
(cherry picked from commit 6e3d69e6b5153e26c869a03ec7dd1aaa40488005)
Signed-off-by: Frode Nordahl 
---
 tests/ovn.at | 72 ++--
 1 file changed, 36 insertions(+), 36 deletions(-)

diff --git a/tests/ovn.at b/tests/ovn.at
index b38f6c9bc..24f83f2c5 100644
--- a/tests/ovn.at
+++ b/tests/ovn.at
@@ -13435,16 +13435,16 @@ ovn-nbctl acl-add ls1 to-lport 3 'ip4.src==10.0.0.1' 
allow
 ovn-nbctl --wait=hv sync
 
 # Check OVS flows, the less restrictive flows should have been installed.
-AT_CHECK([as hv1 ovs-ofctl dump-flows br-int table=45 | \
-grep "priority=1003" | awk '{print $7 " " $8}' | \
+AT_CHECK([as hv1 ovs-ofctl dump-flows br-int table=45 | ofctl_strip_all | \
+grep "priority=1003" | \
 sed 's/conjunction([[^)]]*)/conjunction()/g' | sort], [0], [dnl
-priority=1003,conj_id=2,ip,metadata=0x1 actions=resubmit(,46)
-priority=1003,conj_id=3,ip,metadata=0x1 actions=resubmit(,46)
-priority=1003,ip,metadata=0x1,nw_dst=10.0.0.3 
actions=conjunction(),conjunction()
-priority=1003,ip,metadata=0x1,nw_dst=10.0.0.4 
actions=conjunction(),conjunction()
-priority=1003,ip,metadata=0x1,nw_src=10.0.0.1 actions=resubmit(,46)
-priority=1003,ip,metadata=0x1,nw_src=10.0.0.2 actions=conjunction()
-priority=1003,ip,metadata=0x1,nw_src=10.0.0.42 actions=conjunction()
+ table=45, priority=1003,conj_id=2,ip,metadata=0x1 actions=resubmit(,46)
+ table=45, priority=1003,conj_id=3,ip,metadata=0x1 actions=resubmit(,46)
+ table=45, priority=1003,ip,metadata=0x1,nw_dst=10.0.0.3 
actions=conjunction(),conjunction()
+ table=45, priority=1003,ip,metadata=0x1,nw_dst=10.0.0.4 
actions=conjunction(),conjunction()
+ table=45, priority=1003,ip,metadata=0x1,nw_src=10.0.0.1 actions=resubmit(,46)
+ table=45, priority=1003,ip,metadata=0x1,nw_src=10.0.0.2 actions=conjunction()
+ table=45, priority=1003,ip,metadata=0x1,nw_src=10.0.0.42 actions=conjunction()
 ])
 
 # Traffic 10.0.0.1, 10.0.0.2 -> 10.0.0.3, 10.0.0.4 should be allowed.
@@ -13481,16 +13481,16 @@ ovn-nbctl acl-del ls1 to-lport 3 'ip4.src==10.0.0.1 
|| ip4.src==10.0.0.1'
 ovn-nbctl --wait=hv sync
 
 # Check OVS flows, the second less restrictive allow ACL should have been 
installed.
-AT_CHECK([as hv1 ovs-ofctl dump-flows br-int table=45 | \
-grep "priority=1003" | awk '{print $7 " " $8}' | \
+AT_CHECK([as hv1 ovs-ofctl dump-flows br-int table=45 | ofctl_strip_all | \
+grep "priority=1003" | \
 sed 's/conjunction([[^)]]*)/conjunction()/g' | sort], [0], [dnl
-priority=1003,conj_id=2,ip,metadata=0x1 actions=resubmit(,46)
-priority=1003,conj_id=3,ip,metadata=0x1 actions=resubmit(,46)
-priority=1003,ip,metadata=0x1,nw_dst=10.0.0.3 
actions=conjunction(),conjunction()
-priority=1003,ip,metadata=0x1,nw_dst=10.0.0.4 
actions=conjunction(),conjunction()
-priority=1003,ip,metadata=0x1,nw_src=10.0.0.1 actions=resubmit(,46)
-priority=1003,ip,metadata=0x1,nw_src=10.0.0.2 actions=conjunction()
-priority=1003,ip,metadata=0x1,nw_src=10.0.0.42 actions=conjunction()
+ table=45, priority=1003,conj_id=2,ip,metadata=0x1 actions=resubmit(,46)
+ table=45, priority=1003,conj_id=3,ip,metadata=0x1 actions=resubmit(,46)
+ table=45, priority=1003,ip,metadata=0x1,nw_dst=10.0.0.3 
actions=conjunction(),conjunction()
+ table=45, priority=1003,ip,metadata=0x1,nw_dst=10.0.0.4 
actions=conjunction(),conjunction()
+ table=45, priority=1003,ip,metadata=0x1,nw_src=10.0.0.1 actions=resubmit(,46)
+ table=45, priority=1003,ip,metadata=0x1,nw_src=10.0.0.2 actions=conjunction()
+ table=45, priority=1003,ip,metadata=0x1,nw_src=10.0.0.42 actions=conjunction()
 ])
 
 # Remove the less restrictive allow ACL.
@@ -13498,16 +13498,16 @@ ovn-nbctl acl-del ls1 to-lport 3 'ip4.src==10.0.0.1'
 ovn-nbctl --wait=hv sync
 
 # Check OVS flows, the 10.0.0.1 conjunction should have been reinstalled.
-AT_CHECK([as hv1 ovs-ofctl dump-flows br-int table=45 | \
-grep "priority=1003" | awk '{print $7 " " $8}' | \
+AT_CHECK([as hv1 ovs-ofctl dump-flows br-int table=45 | ofctl_strip_all | \
+grep "priority=1003" | \
 sed 's/conjunction([[^)]]*)/conjunction()/g' | sort], [0], [dnl
-priority=1003,conj_id=2,ip,metadata=0x1 actions=resubmit(,46)
-priority=1003,conj_id=3,ip,metadata=0x1 actions=resubmit(,46)
-priority=1003,ip,metadata=0x1,nw_dst=10.0.0.3 
actions=conjunction(),conjunction()
-priority=1003,ip,metadata=0x1,nw_dst=10.0.0.4 
actions=conjunction(),conjunction()
-priority=1003,ip,metadata=0x1,nw_src=10.0.0.1 
actions=conjunction(),conjunction()
-priority=1003,ip,metadata=0x1,nw_src=10.0.0.2 actions=conjunction()
-priority=1003,ip,metadata=0x1,nw_src=10.0.0.42 actions=conjunction()
+ table=45, 

[ovs-dev] [PATCH ovn branch-20.06 14/15] tests: Add ofctl_strip_all() to filter OVS flow outputs.

2021-02-18 Thread Dumitru Ceara
Extend the already existing ofctl_strip() to also ignore n_packets,
n_bytes, cookie.  Use some helper functions from
tests/system-userspace-packet-type-aware.at, which will be removed
by a future commit.

Signed-off-by: Dumitru Ceara 
Signed-off-by: Numan Siddique 
(cherry picked from commit 0879a0aa9f332bdc689769a1bc2f156f1c3149a5)
Signed-off-by: Frode Nordahl 
---
 tests/ofproto-macros.at | 23 ++-
 1 file changed, 22 insertions(+), 1 deletion(-)

diff --git a/tests/ofproto-macros.at b/tests/ofproto-macros.at
index 6c4ff60e7..22999c1ca 100644
--- a/tests/ofproto-macros.at
+++ b/tests/ofproto-macros.at
@@ -1,12 +1,27 @@
 m4_divert_push([PREPARE_TESTS])
 [
+# Strips 'n_packets=...' from ovs-ofctl output.
+strip_n_packets () {
+sed 's/ n_packets=[0-9]*,//'
+}
+
+# Strips 'n_bytes=...' from ovs-ofctl output.
+strip_n_bytes () {
+sed 's/ n_bytes=[0-9]*,//'
+}
+
+# Strips 'cookie=...' from ovs-ofctl output.
+strip_cookie () {
+sed 's/ cookie=0x[0-9a-fA-F]*,//'
+}
+
 # Strips out uninteresting parts of ovs-ofctl output, as well as parts
 # that vary from one run to another.
 ofctl_strip () {
 sed '
 s/ (xid=0x[0-9a-fA-F]*)//
 s/ duration=[0-9.]*s,//
-s/ cookie=0x0,//
+s/ cookie=0,//
 s/ table=0,//
 s/ n_packets=0,//
 s/ n_bytes=0,//
@@ -19,6 +34,12 @@ s/dir\/[0-9]*\/br0.mgmt/dir\/\/br0.mgmt/
 '
 }
 
+# Strips out uninteresting parts of ovs-ofctl output, including n_packets=..
+# n_bytes=..
+ofctl_strip_all () {
+ofctl_strip | strip_n_packets | strip_n_bytes | strip_cookie
+}
+
 # Filter (multiline) vconn debug messages from ovs-vswitchd.log.
 # Use with vconn_sub() and ofctl_strip()
 print_vconn_debug () { awk -F\| < ovs-vswitchd.log '
-- 
2.30.0
___
dev mailing list
d...@openvswitch.org
https://mail.openvswitch.org/mailman/listinfo/ovs-dev


[ovs-dev] [PATCH ovn branch-20.06 13/15] ovn.at: Make some of the tests more predictable.

2021-02-18 Thread Dumitru Ceara
Fix some of the race conditions that are present in the current OVN test
suite.

Signed-off-by: Dumitru Ceara 
Signed-off-by: Ben Pfaff 
(cherry picked from commit d6594a4695084e1b0f4fb3170547942876d3a81a)
Signed-off-by: Frode Nordahl 
---
 tests/ovn.at | 48 +++-
 1 file changed, 27 insertions(+), 21 deletions(-)

diff --git a/tests/ovn.at b/tests/ovn.at
index 8f7dec55d..b38f6c9bc 100644
--- a/tests/ovn.at
+++ b/tests/ovn.at
@@ -4045,6 +4045,7 @@ for i in 1 2 3; do
 ovn-nbctl lsp-set-addresses lp$i$j "f0:00:00:00:00:$i$j 
192.168.0.$i$j" "$extra_addr"
 ovn-nbctl lsp-set-port-security lp$i$j "f0:00:00:00:00:$i$j 
192.168.0.$i$j" "$extra_addr"
 fi
+OVS_WAIT_UNTIL([test x`ovn-nbctl lsp-get-up lp$i$j` = xup])
 done
 done
 
@@ -13435,14 +13436,15 @@ ovn-nbctl --wait=hv sync
 
 # Check OVS flows, the less restrictive flows should have been installed.
 AT_CHECK([as hv1 ovs-ofctl dump-flows br-int table=45 | \
-grep "priority=1003" | awk '{print $7 " " $8}' | sort], [0], [dnl
+grep "priority=1003" | awk '{print $7 " " $8}' | \
+sed 's/conjunction([[^)]]*)/conjunction()/g' | sort], [0], [dnl
 priority=1003,conj_id=2,ip,metadata=0x1 actions=resubmit(,46)
 priority=1003,conj_id=3,ip,metadata=0x1 actions=resubmit(,46)
-priority=1003,ip,metadata=0x1,nw_dst=10.0.0.3 
actions=conjunction(2,1/2),conjunction(3,1/2)
-priority=1003,ip,metadata=0x1,nw_dst=10.0.0.4 
actions=conjunction(2,1/2),conjunction(3,1/2)
+priority=1003,ip,metadata=0x1,nw_dst=10.0.0.3 
actions=conjunction(),conjunction()
+priority=1003,ip,metadata=0x1,nw_dst=10.0.0.4 
actions=conjunction(),conjunction()
 priority=1003,ip,metadata=0x1,nw_src=10.0.0.1 actions=resubmit(,46)
-priority=1003,ip,metadata=0x1,nw_src=10.0.0.2 actions=conjunction(2,2/2)
-priority=1003,ip,metadata=0x1,nw_src=10.0.0.42 actions=conjunction(3,2/2)
+priority=1003,ip,metadata=0x1,nw_src=10.0.0.2 actions=conjunction()
+priority=1003,ip,metadata=0x1,nw_src=10.0.0.42 actions=conjunction()
 ])
 
 # Traffic 10.0.0.1, 10.0.0.2 -> 10.0.0.3, 10.0.0.4 should be allowed.
@@ -13480,14 +13482,15 @@ ovn-nbctl --wait=hv sync
 
 # Check OVS flows, the second less restrictive allow ACL should have been 
installed.
 AT_CHECK([as hv1 ovs-ofctl dump-flows br-int table=45 | \
-grep "priority=1003" | awk '{print $7 " " $8}' | sort], [0], [dnl
+grep "priority=1003" | awk '{print $7 " " $8}' | \
+sed 's/conjunction([[^)]]*)/conjunction()/g' | sort], [0], [dnl
 priority=1003,conj_id=2,ip,metadata=0x1 actions=resubmit(,46)
 priority=1003,conj_id=3,ip,metadata=0x1 actions=resubmit(,46)
-priority=1003,ip,metadata=0x1,nw_dst=10.0.0.3 
actions=conjunction(2,1/2),conjunction(3,1/2)
-priority=1003,ip,metadata=0x1,nw_dst=10.0.0.4 
actions=conjunction(2,1/2),conjunction(3,1/2)
+priority=1003,ip,metadata=0x1,nw_dst=10.0.0.3 
actions=conjunction(),conjunction()
+priority=1003,ip,metadata=0x1,nw_dst=10.0.0.4 
actions=conjunction(),conjunction()
 priority=1003,ip,metadata=0x1,nw_src=10.0.0.1 actions=resubmit(,46)
-priority=1003,ip,metadata=0x1,nw_src=10.0.0.2 actions=conjunction(2,2/2)
-priority=1003,ip,metadata=0x1,nw_src=10.0.0.42 actions=conjunction(3,2/2)
+priority=1003,ip,metadata=0x1,nw_src=10.0.0.2 actions=conjunction()
+priority=1003,ip,metadata=0x1,nw_src=10.0.0.42 actions=conjunction()
 ])
 
 # Remove the less restrictive allow ACL.
@@ -13496,14 +13499,15 @@ ovn-nbctl --wait=hv sync
 
 # Check OVS flows, the 10.0.0.1 conjunction should have been reinstalled.
 AT_CHECK([as hv1 ovs-ofctl dump-flows br-int table=45 | \
-grep "priority=1003" | awk '{print $7 " " $8}' | sort], [0], [dnl
+grep "priority=1003" | awk '{print $7 " " $8}' | \
+sed 's/conjunction([[^)]]*)/conjunction()/g' | sort], [0], [dnl
 priority=1003,conj_id=2,ip,metadata=0x1 actions=resubmit(,46)
 priority=1003,conj_id=3,ip,metadata=0x1 actions=resubmit(,46)
-priority=1003,ip,metadata=0x1,nw_dst=10.0.0.3 
actions=conjunction(2,1/2),conjunction(3,1/2)
-priority=1003,ip,metadata=0x1,nw_dst=10.0.0.4 
actions=conjunction(2,1/2),conjunction(3,1/2)
-priority=1003,ip,metadata=0x1,nw_src=10.0.0.1 
actions=conjunction(2,2/2),conjunction(3,2/2)
-priority=1003,ip,metadata=0x1,nw_src=10.0.0.2 actions=conjunction(2,2/2)
-priority=1003,ip,metadata=0x1,nw_src=10.0.0.42 actions=conjunction(3,2/2)
+priority=1003,ip,metadata=0x1,nw_dst=10.0.0.3 
actions=conjunction(),conjunction()
+priority=1003,ip,metadata=0x1,nw_dst=10.0.0.4 
actions=conjunction(),conjunction()
+priority=1003,ip,metadata=0x1,nw_src=10.0.0.1 
actions=conjunction(),conjunction()
+priority=1003,ip,metadata=0x1,nw_src=10.0.0.2 actions=conjunction()
+priority=1003,ip,metadata=0x1,nw_src=10.0.0.42 actions=conjunction()
 ])
 
 # Traffic 10.0.0.1, 10.0.0.2 -> 10.0.0.3, 10.0.0.4 should be allowed.
@@ -13534,14 +13538,15 @@ ovn-nbctl --wait=hv sync
 
 # Check OVS flows, the less restrictive flows should have been installed.
 AT_CHECK([as hv1 ovs-ofctl dump-flows br-int table=45 | \
-   

[ovs-dev] [PATCH ovn branch-20.06 12/15] ofctrl.c: Add a predictable resolution for conflicting flow actions.

2021-02-18 Thread Dumitru Ceara
Until now, in case the ACL configuration generates openflows that have
the same match but different actions, ovn-controller was using the
following approach:
1. If the flow being added contains conjunctive actions, merge its
   actions with the already existing flow.
2. Otherwise, if the flow is being added incrementally
   (update_installed_flows_by_track), don't install the new flow but
   instead keep the old one.
3. Otherwise, (update_installed_flows_by_compare), don't install the
   new flow but instead keep the old one.

Even though one can argue that having an ACL with a match that includes
the match of another ACL is a misconfiguration, it can happen that the
users provision OVN like this.  Depending on the order of reading and
installing the logical flows, the above operations can yield
unpredictable results, e.g., allow specific traffic but then after
ovn-controller is restarted (or a recompute happens) that specific
traffic starts being dropped.

A simple example of ACL configuration is:
ovn-nbctl acl-add ls to-lport 3 '(ip4.src==10.0.0.1 ||
ip4.src==10.0.0.2) && (ip4.dst == 10.0.0.3 || ip4.dst == 10.0.0.4)' allow
ovn-nbctl acl-add ls to-lport 3 'ip4.src==10.0.0.1' allow
ovn-nbctl acl-add ls to-lport 2 'arp' allow
ovn-nbctl acl-add ls to-lport 1 'ip4' drop

This is a pattern used by most CMSs:
- define a default deny policy.
- punch holes in the default deny policy based on user specific
  configurations.

Without this commit the behavior for traffic from 10.0.0.1 to 10.0.0.5
is unpredictable.  Depending on the order of operations traffic might be
dropped or allowed.

It's also quite hard to force the CMS to ensure that such match overlaps
never occur.

To address this issue we now ensure that all desired flows refering the
same installed flow are partially sorted in the following way:
- first all flows with action "allow".
- then all flows with action "drop".
- then a single flow with action "conjunction" (resulting from merging
  all flows with the same match and action conjunction).

This ensures that "allow" flows have precedence over "drop" flows which
in turn have precedence over "conjunction" flows.  Essentially less
restrictive flows are always preferred over more restrictive flows whenever a 
match
conflict happens.

CC: Daniel Alvarez 
Reported-at: https://bugzilla.redhat.com/1871931
Signed-off-by: Dumitru Ceara 
Acked-by: Mark Gray 
Signed-off-by: Han Zhou 
(cherry picked from commit 986b3d5e4ad6f05245d021ba699c957246294a22)
Signed-off-by: Frode Nordahl 
---
 controller/ofctrl.c |  74 +--
 tests/ovn.at| 214 
 2 files changed, 283 insertions(+), 5 deletions(-)

diff --git a/controller/ofctrl.c b/controller/ofctrl.c
index 16dc10cfb..c1bbc589e 100644
--- a/controller/ofctrl.c
+++ b/controller/ofctrl.c
@@ -188,6 +188,14 @@ struct sb_flow_ref {
  * relationship is 1 to N. A link is added when a flow addition is processed.
  * A link is removed when a flow deletion is processed, the desired flow
  * table is cleared, or the installed flow table is cleared.
+ *
+ * To ensure predictable behavior, the list of desired flows is maintained
+ * partially sorted in the following way (from least restrictive to most
+ * restrictive wrt. match):
+ * - allow flows without action conjunction.
+ * - drop flows without action conjunction.
+ * - a single flow with action conjunction.
+ *
  * The first desired_flow in the list is the active one, the one that is
  * actually installed.
  */
@@ -795,6 +803,12 @@ ofctrl_recv(const struct ofp_header *oh, enum ofptype type)
 }
 }
 
+static bool
+flow_action_has_drop(const struct ovn_flow *f)
+{
+return f->ofpacts_len == 0;
+}
+
 static bool
 flow_action_has_conj(const struct ovn_flow *f)
 {
@@ -808,6 +822,33 @@ flow_action_has_conj(const struct ovn_flow *f)
 return false;
 }
 
+static bool
+flow_action_has_allow(const struct ovn_flow *f)
+{
+return !flow_action_has_drop(f) && !flow_action_has_conj(f);
+}
+
+/* Returns true if flow 'a' is preferred over flow 'b'. */
+static bool
+flow_is_preferred(const struct ovn_flow *a, const struct ovn_flow *b)
+{
+if (flow_action_has_allow(b)) {
+return false;
+}
+if (flow_action_has_allow(a)) {
+return true;
+}
+if (flow_action_has_drop(b)) {
+return false;
+}
+if (flow_action_has_drop(a)) {
+return true;
+}
+
+/* Flows 'a' and 'b' should never both have action conjunction. */
+OVS_NOT_REACHED();
+}
+
 /* Adds the desired flow to the list of desired flows that have same match
  * conditions as the installed flow.
  *
@@ -820,8 +861,18 @@ flow_action_has_conj(const struct ovn_flow *f)
 static bool
 link_installed_to_desired(struct installed_flow *i, struct desired_flow *d)
 {
+struct desired_flow *f;
+
+/* Find first 'f' such that 'd' is preferred over 'f'.  If no such desired
+ * flow exists then 'f' will point after the last element of the list.
+ */
+

[ovs-dev] [PATCH ovn branch-20.06 11/15] ofctrl.c: Always log the most recent flow changes.

2021-02-18 Thread Dumitru Ceara
Fixes: 6f0b1e02d9ab ("ofctrl: Incremental processing for flow installation by 
tracking.")
Signed-off-by: Dumitru Ceara 
Signed-off-by: Han Zhou 
(cherry picked from commit 33c15c145988daa6172928dc870f3a0225515f50)
Signed-off-by: Frode Nordahl 
---
 controller/ofctrl.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/controller/ofctrl.c b/controller/ofctrl.c
index c03c2d7b4..16dc10cfb 100644
--- a/controller/ofctrl.c
+++ b/controller/ofctrl.c
@@ -1895,8 +1895,8 @@ update_installed_flows_by_track(struct 
ovn_desired_flow_table *flow_table,
  * installed flow, so update the OVS flow for the new
  * active flow (at least the cookie will be different,
  * even if the actions are the same). */
-ovn_flow_log(>flow, "updating installed (tracked)");
 installed_flow_mod(>flow, >flow, msgs);
+ovn_flow_log(>flow, "updating installed (tracked)");
 }
 }
 desired_flow_destroy(f);
@@ -1916,8 +1916,8 @@ update_installed_flows_by_track(struct 
ovn_desired_flow_table *flow_table,
 } else if (installed_flow_get_active(i) == f) {
 /* The installed flow is installed for f, but f has change
  * tracked, so it must have been modified. */
-ovn_flow_log(>flow, "updating installed (tracked)");
 installed_flow_mod(>flow, >flow, msgs);
+ovn_flow_log(>flow, "updating installed (tracked)");
 } else {
 /* Adding a new flow that conflicts with an existing installed
  * flow, so just add it to the link. */
-- 
2.30.0
___
dev mailing list
d...@openvswitch.org
https://mail.openvswitch.org/mailman/listinfo/ovs-dev


[ovs-dev] [PATCH ovn branch-20.06 10/15] ofctrl.c: Simplify active desired flow selection.

2021-02-18 Thread Dumitru Ceara
Always consider the first "desired flow" in the list of flows that refer an
"installed flow" as the active flow.  This simplifies the logic of the flow
update code and is used in a further commit to implement a partial ordering
of desired flows within installed flows.

Signed-off-by: Dumitru Ceara 
Signed-off-by: Han Zhou 
(cherry picked from commit 107bb25029350bd0f7dfeeb0ef3053adbd504e3e)
Signed-off-by: Frode Nordahl 
---
 controller/ofctrl.c | 91 ++---
 1 file changed, 36 insertions(+), 55 deletions(-)

diff --git a/controller/ofctrl.c b/controller/ofctrl.c
index 0262a5cc3..c03c2d7b4 100644
--- a/controller/ofctrl.c
+++ b/controller/ofctrl.c
@@ -188,6 +188,8 @@ struct sb_flow_ref {
  * relationship is 1 to N. A link is added when a flow addition is processed.
  * A link is removed when a flow deletion is processed, the desired flow
  * table is cleared, or the installed flow table is cleared.
+ * The first desired_flow in the list is the active one, the one that is
+ * actually installed.
  */
 struct installed_flow {
 struct ovn_flow flow;
@@ -199,11 +201,6 @@ struct installed_flow {
  * installed flow, e.g. when there are conflict/duplicated ACLs that
  * generates same match conditions). */
 struct ovs_list desired_refs;
-
-/* The corresponding flow in desired table. It must be one of the flows in
- * desired_refs list.  If there are more than one flows in references list,
- * this is the one that is actually installed. */
-struct desired_flow *desired_flow;
 };
 
 typedef bool
@@ -231,6 +228,7 @@ static struct installed_flow *installed_flow_lookup(
 const struct ovn_flow *target);
 static void installed_flow_destroy(struct installed_flow *);
 static struct installed_flow *installed_flow_dup(struct desired_flow *);
+static struct desired_flow *installed_flow_get_active(struct installed_flow *);
 
 static uint32_t ovn_flow_match_hash(const struct ovn_flow *);
 static char *ovn_flow_to_string(const struct ovn_flow *);
@@ -796,24 +794,6 @@ ofctrl_recv(const struct ofp_header *oh, enum ofptype type)
 log_openflow_rl(, VLL_DBG, oh, "OpenFlow packet ignored");
 }
 }
-

-/* Returns true if a desired flow is active (the one currently installed
- * among the list of desired flows that are linked to the same installed
- * flow). */
-static inline bool
-desired_flow_is_active(struct desired_flow *d)
-{
-return (d->installed_flow && d->installed_flow->desired_flow == d);
-}
-
-/* Set a desired flow as the active one among the list of desired flows
- * that are linked to the same installed flow. */
-static inline void
-desired_flow_set_active(struct desired_flow *d)
-{
-ovs_assert(d->installed_flow);
-d->installed_flow->desired_flow = d;
-}
 
 static bool
 flow_action_has_conj(const struct ovn_flow *f)
@@ -831,27 +811,22 @@ flow_action_has_conj(const struct ovn_flow *f)
 /* Adds the desired flow to the list of desired flows that have same match
  * conditions as the installed flow.
  *
- * If the newly added desired flow is the first one in the list, it is also set
- * as the active one.
- *
  * It is caller's responsibility to make sure the link between the pair didn't
- * exist before. */
-static void
+ * exist before.
+ *
+ * Returns true if the newly added desired flow is selected to be the active
+ * one.
+ */
+static bool
 link_installed_to_desired(struct installed_flow *i, struct desired_flow *d)
 {
-ovs_assert(i->desired_flow != d);
-if (ovs_list_is_empty(>desired_refs)) {
-ovs_assert(!i->desired_flow);
-i->desired_flow = d;
-}
-ovs_list_insert(>desired_refs, >installed_ref_list_node);
 d->installed_flow = i;
+ovs_list_push_back(>desired_refs, >installed_ref_list_node);
+return installed_flow_get_active(i) == d;
 }
 
 /* Replaces 'old_desired' with 'new_desired' in the list of desired flows
  * that have same match conditions as the installed flow.
- *
- * If 'old_desired' was the active flow, 'new_desired' becomes the active one.
  */
 static void
 replace_installed_to_desired(struct installed_flow *i,
@@ -863,24 +838,22 @@ replace_installed_to_desired(struct installed_flow *i,
  _desired->installed_ref_list_node);
 old_desired->installed_flow = NULL;
 new_desired->installed_flow = i;
-if (i->desired_flow == old_desired) {
-i->desired_flow = new_desired;
-}
 }
 
-static void
+/* Removes the desired flow from the list of desired flows that have the same
+ * match conditions as the installed flow.
+ *
+ * Returns true if the desired flow was the previously active flow.
+ */
+static bool
 unlink_installed_to_desired(struct installed_flow *i, struct desired_flow *d)
 {
-ovs_assert(i && i->desired_flow && !ovs_list_is_empty(>desired_refs));
+struct desired_flow *old_active = installed_flow_get_active(i);
+
 ovs_assert(d && d->installed_flow == i);
 ovs_list_remove(>installed_ref_list_node);
 

[ovs-dev] [PATCH ovn branch-20.06 09/15] ofctrl.c: Do not change flow ordering when merging opposite changes.

2021-02-18 Thread Dumitru Ceara
Instead of removing the old desired flow from the list and inserting the new
one at the end we now directly replace the old flow with the new one while
maintaining the same ordering.

For now order of the flows is not relevant but further commits require
maintaining the order of desired flows.

Signed-off-by: Dumitru Ceara 
Signed-off-by: Han Zhou 
(cherry picked from commit e49ce9a33f38f29c44e3c30afcc189b5f6a9ef8e)
Signed-off-by: Frode Nordahl 
---
 controller/ofctrl.c | 28 +---
 1 file changed, 21 insertions(+), 7 deletions(-)

diff --git a/controller/ofctrl.c b/controller/ofctrl.c
index 8404479bc..0262a5cc3 100644
--- a/controller/ofctrl.c
+++ b/controller/ofctrl.c
@@ -848,6 +848,26 @@ link_installed_to_desired(struct installed_flow *i, struct 
desired_flow *d)
 d->installed_flow = i;
 }
 
+/* Replaces 'old_desired' with 'new_desired' in the list of desired flows
+ * that have same match conditions as the installed flow.
+ *
+ * If 'old_desired' was the active flow, 'new_desired' becomes the active one.
+ */
+static void
+replace_installed_to_desired(struct installed_flow *i,
+ struct desired_flow *old_desired,
+ struct desired_flow *new_desired)
+{
+ovs_assert(old_desired->installed_flow == i);
+ovs_list_replace(_desired->installed_ref_list_node,
+ _desired->installed_ref_list_node);
+old_desired->installed_flow = NULL;
+new_desired->installed_flow = i;
+if (i->desired_flow == old_desired) {
+i->desired_flow = new_desired;
+}
+}
+
 static void
 unlink_installed_to_desired(struct installed_flow *i, struct desired_flow *d)
 {
@@ -1843,21 +1863,15 @@ merge_tracked_flows(struct ovn_desired_flow_table 
*flow_table)
  * removed during track_flow_add_or_modify. */
 ovs_assert(del_f->installed_flow);
 
-bool del_f_was_active = desired_flow_is_active(del_f);
 if (!f->installed_flow) {
 /* f is not installed yet. */
-struct installed_flow *i = del_f->installed_flow;
-unlink_installed_to_desired(i, del_f);
-link_installed_to_desired(i, f);
+replace_installed_to_desired(del_f->installed_flow, del_f, f);
 } else {
 /* f has been installed before, and now was updated to exact
  * the same flow as del_f. */
 ovs_assert(f->installed_flow == del_f->installed_flow);
 unlink_installed_to_desired(del_f->installed_flow, del_f);
 }
-if (del_f_was_active) {
-desired_flow_set_active(f);
-}
 hmap_remove(_flows, _f->match_hmap_node);
 ovs_list_remove(_f->track_list_node);
 desired_flow_destroy(del_f);
-- 
2.30.0
___
dev mailing list
d...@openvswitch.org
https://mail.openvswitch.org/mailman/listinfo/ovs-dev


[ovs-dev] [PATCH ovn branch-20.06 08/15] ofctrl.c: Only merge actions for conjunctive flows.

2021-02-18 Thread Dumitru Ceara
In ofctrl_add_or_append_flow() when merging flow actions make sure we only
do that for conjunctive flows.  All other actions can not be merged with
action "conjunction".

CC: Mark Michelson 
Fixes: e659bab31a91 ("Combine conjunctions with identical matches into one 
flow.")
Signed-off-by: Dumitru Ceara 
Signed-off-by: Han Zhou 
(cherry picked from commit dadae4f800ccb1f2759378f0bd804dd002e31605)
Signed-off-by: Frode Nordahl 
---
 controller/ofctrl.c | 124 +++-
 1 file changed, 99 insertions(+), 25 deletions(-)

diff --git a/controller/ofctrl.c b/controller/ofctrl.c
index 384659d0c..8404479bc 100644
--- a/controller/ofctrl.c
+++ b/controller/ofctrl.c
@@ -206,6 +206,9 @@ struct installed_flow {
 struct desired_flow *desired_flow;
 };
 
+typedef bool
+(*desired_flow_match_cb)(const struct desired_flow *candidate,
+ const void *arg);
 static struct desired_flow *desired_flow_alloc(
 uint8_t table_id,
 uint16_t priority,
@@ -213,9 +216,15 @@ static struct desired_flow *desired_flow_alloc(
 const struct match *match,
 const struct ofpbuf *actions);
 static struct desired_flow *desired_flow_lookup(
+struct ovn_desired_flow_table *,
+const struct ovn_flow *target);
+static struct desired_flow *desired_flow_lookup_check_uuid(
 struct ovn_desired_flow_table *,
 const struct ovn_flow *target,
-const struct uuid *sb_uuid);
+const struct uuid *);
+static struct desired_flow *desired_flow_lookup_conjunctive(
+struct ovn_desired_flow_table *,
+const struct ovn_flow *target);
 static void desired_flow_destroy(struct desired_flow *);
 
 static struct installed_flow *installed_flow_lookup(
@@ -806,6 +815,19 @@ desired_flow_set_active(struct desired_flow *d)
 d->installed_flow->desired_flow = d;
 }
 
+static bool
+flow_action_has_conj(const struct ovn_flow *f)
+{
+const struct ofpact *a = NULL;
+
+OFPACT_FOR_EACH (a, f->ofpacts, f->ofpacts_len) {
+if (a->type == OFPACT_CONJUNCTION) {
+return true;
+}
+}
+return false;
+}
+
 /* Adds the desired flow to the list of desired flows that have same match
  * conditions as the installed flow.
  *
@@ -962,7 +984,7 @@ ofctrl_check_and_add_flow(struct ovn_desired_flow_table 
*flow_table,
 struct desired_flow *f = desired_flow_alloc(table_id, priority, cookie,
 match, actions);
 
-if (desired_flow_lookup(flow_table, >flow, sb_uuid)) {
+if (desired_flow_lookup_check_uuid(flow_table, >flow, sb_uuid)) {
 if (log_duplicate_flow) {
 static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(5, 5);
 if (!VLOG_DROP_DBG()) {
@@ -1002,14 +1024,15 @@ ofctrl_add_or_append_flow(struct ovn_desired_flow_table 
*desired_flows,
   const struct ofpbuf *actions,
   const struct uuid *sb_uuid)
 {
-struct desired_flow *f = desired_flow_alloc(table_id, priority, cookie,
-match, actions);
-
 struct desired_flow *existing;
-existing = desired_flow_lookup(desired_flows, >flow, NULL);
+struct desired_flow *f;
+
+f = desired_flow_alloc(table_id, priority, cookie, match, actions);
+existing = desired_flow_lookup_conjunctive(desired_flows, >flow);
 if (existing) {
-/* There's already a flow with this particular match. Append the
- * action to that flow rather than adding a new flow
+/* There's already a flow with this particular match and action
+ * 'conjunction'. Append the action to that flow rather than
+ * adding a new flow.
  */
 uint64_t compound_stub[64 / 8];
 struct ofpbuf compound;
@@ -1248,15 +1271,11 @@ installed_flow_dup(struct desired_flow *src)
 return dst;
 }
 
-/* Finds and returns a desired_flow in 'flow_table' whose key is identical to
- * 'target''s key, or NULL if there is none.
- *
- * If sb_uuid is not NULL, the function will also check if the found flow is
- * referenced by the sb_uuid. */
 static struct desired_flow *
-desired_flow_lookup(struct ovn_desired_flow_table *flow_table,
-const struct ovn_flow *target,
-const struct uuid *sb_uuid)
+desired_flow_lookup__(struct ovn_desired_flow_table *flow_table,
+  const struct ovn_flow *target,
+  desired_flow_match_cb match_cb,
+  const void *arg)
 {
 struct desired_flow *d;
 HMAP_FOR_EACH_WITH_HASH (d, match_hmap_node, target->hash,
@@ -1265,20 +1284,76 @@ desired_flow_lookup(struct ovn_desired_flow_table 
*flow_table,
 if (f->table_id == target->table_id
 && f->priority == target->priority
 && minimatch_equal(>match, >match)) {
-if (!sb_uuid) {
+
+if (!match_cb || match_cb(d, arg)) {
 return d;
 }
-struct 

Re: [ovs-dev] [RFC ovn] northd: set max priority for automatic routes

2021-02-18 Thread Dumitru Ceara

Hi guys,

On 2/18/21 12:16 AM, Han Zhou wrote:

On Wed, Feb 17, 2021 at 2:36 PM Tim Rozet  wrote:





On Tue, Feb 16, 2021 at 4:21 AM Han Zhou  wrote:




On Wed, Feb 10, 2021 at 2:17 PM Lorenzo Bianconi <

lorenzo.bianc...@redhat.com> wrote:


Increase priority for automatic routes (routes created assigning IP
addresses to OVN logical router interfaces) in order to always prefer

them

over static routes since the router has a direct link to the

destination

address (possible use-case can be found here [0]).

[0] https://bugzilla.redhat.com/show_bug.cgi?id=1891516



Hi Lorenzo, Tim,

While the patch may solve the problem in the bug report, I think there

is something more fundamental to be discussed. The problem is caused by
ovn-k8s's use of "src-ip" in static routes which overrides the
direct-connected route. I think the implementation of "src-ip" support in
the static route is somehow flawed. The priorities of the flows generated
by static routes are calculated according to the prefix length, so that
longest prefix routes are prioritised when there are multiple route
matches, which is correct when comparing matches among "dst-ip" routes or
among "src-ip" routes, but is not correct between "dst-ip" and "src-ip"
routes. Comparison of prefix length between these two types of static
routes doesn't make sense, because they match by different fields (src-ip
v.s. dst-ip). For example, when there are static routes:

1. 192.168.0.0/24 via 100.64.0.1 src-ip
2. 10.0.0.0/20 via 100.64.0.2 dst-ip

In this example, a packet from 192.168.0.1 to 10.0.0.1 matches both

routes, but it is unreasonable to say it should follow the 1st route just
because it has longer prefix length. Instead, we should prioritize one type
over the other. It seems in physical router implementation policy based
routing always has higher priority than destination routing, so we should
probably enforce it in a similar way in OVN, i.e. set "src-ip" flows with
higher priority than all the "dst-ip" flows. In fact, the policy routing
table already supported this behavior because it is examined before the
static route table.


Since the "src-ip" feature in the static route table is flawed, and can

be replaced by the policy routing table, I'd suggest to deprecate it. For


I agree.


correctness, users (like ovn-k8s) should use the policy routing table
instead for the src-ip based routing rules. Users have full control of how
they want the packets to be routed. For the use case mentioned in the bug
report, it should have two rules in the policy routing table:



100 ip.dst == 100.64.0.0/16 accept # for directly connected destination,

skip the src-ip rules

90   ip.src == 10.244.0.0/24 nexthop 100.64.0.1 # src-ip rules

Would this better satisfy the need of ovn-k8s?



I believe this is correct. src-ip matching should be done in the policy

table so traditional dest based routing is handled in default routing
table. Need to go double check though.


One example, but should be the same for all "traditional" routers, "The 
Policy-Based Routing feature is a process whereby a device puts packets 
through a route map before routing the packets.":


https://www.cisco.com/c/en/us/td/docs/ios-xml/ios/iproute_pi/configuration/15-mt/iri-15-mt-book/iri-pbr.html





If the above is agreed, the priority change of directly connected routes

from this patch is irrelevant to the problem reported in the bug, because
policy routing rules are examined before the static routing table anyway,
so no matter how high the route priority is, it wouldn't matter. In
addition, it seems to me no real use cases would benefit from this change,
but I could be wrong and please correct me if so.



I disagree with this. Trying to override a directly connected route is

fundamentally wrong, which is why real routers specifically stop a user
from being able to do this. What if a user who had a router attached to
100.64.0.0/16, adds a /32 route for 100.64.0.1 via another
interface/subnet? That would take precedence over the directly attached
route in OVN iiuc and pretty much guarantee improper networking. Directly
connected routes should always take precedence, and therefore the default
route lflows that get installed should always have the highest possible
priority.


I think there's some confusion here.

In "traditional" routers, longest prefix match has priority in the route 
selection process.


If two routes (from different protocols, including "directly connected") 
are available for the *same* prefix *and* length then, and only then, 
the one with the lowest administrative distance is selected.  Most of 
the times "directly connected" routes have a lower admin distance by 
default compared to static routes so they are preferred *if* such a 
selection has to happen.


The admin distance is also usually configurable (although not usually 
recommended) and allows users to override the default preference of routes.


Back to the example above, in a "traditional" router, when the 

[ovs-dev] [PATCH ovn branch-20.06 06/15] ofctrl.c: Fix duplicated flow handling in I-P while merging opposite changes.

2021-02-18 Thread Han Zhou
In a scenario in I-P when a desired flow is removed and an exactly same flow is
added back in the same iteration, the merge_tracked_flows() function will merge
the operation without firing any OpenFlow action. However, if there are
multiple desired flows (e.g. F1 and F2) matching the same installed flow, and
if the one being re-added (say, F1) is the one currently installed in OVS, the
current implementation will update the currently installed flow to F2 in the
data structure while the actual OVS flow is not updated (still F1). So far
there is still no problem, but the member desired_flow of the installed flow
is pointing to the wrong desired flow.

Now there is only one place where the desired_flow member is consulted, in
update_installed_flows_by_track() for handling a tracked *modified* flow. In
reality flow modification happens only when conjunction flows need to be
combined, which would never happen together with the above scenario of
merge_tracked_flows(). So this wrong desired_flow pointer doesn't cause any
real problem yet.

However, there is a place that can already utilize this active desired_flow
information, which is when handling a tracked flow deletion in
update_installed_flows_by_track(): we can check if the flow being deleted is
the currently active one installed in OVS. If not, we don't need to send and
OpenFlow modify to OVS. This optimization is added in this patch, apart from
fixing the problem of merge_tracked_flows(). Without the fix, this optimization
would cause the test case added in this patch fail.

Fixes: f4e508dd7 ("ofctrl.c: Merge opposite changes of tracked flows before 
installing.")
Acked-by: Dumitru Ceara 
Signed-off-by: Han Zhou 
(cherry picked from commit 9d2e8d32fb9865513b70408a665184a67564390d)
Signed-off-by: Frode Nordahl 
---
 controller/ofctrl.c |  28 +++-
 tests/ovn.at| 108 
 2 files changed, 134 insertions(+), 2 deletions(-)

diff --git a/controller/ofctrl.c b/controller/ofctrl.c
index 2d0e15978..3225e6c67 100644
--- a/controller/ofctrl.c
+++ b/controller/ofctrl.c
@@ -788,6 +788,24 @@ ofctrl_recv(const struct ofp_header *oh, enum ofptype type)
 }
 }
 

+/* Returns true if a desired flow is active (the one currently installed
+ * among the list of desired flows that are linked to the same installed
+ * flow). */
+static inline bool
+desired_flow_is_active(struct desired_flow *d)
+{
+return (d->installed_flow && d->installed_flow->desired_flow == d);
+}
+
+/* Set a desired flow as the active one among the list of desired flows
+ * that are linked to the same installed flow. */
+static inline void
+desired_flow_set_active(struct desired_flow *d)
+{
+ovs_assert(d->installed_flow);
+d->installed_flow->desired_flow = d;
+}
+
 static void
 link_installed_to_desired(struct installed_flow *i, struct desired_flow *d)
 {
@@ -1741,6 +1759,8 @@ merge_tracked_flows(struct ovn_desired_flow_table 
*flow_table)
 /* del_f must have been installed, otherwise it should have been
  * removed during track_flow_add_or_modify. */
 ovs_assert(del_f->installed_flow);
+
+bool del_f_was_active = desired_flow_is_active(del_f);
 if (!f->installed_flow) {
 /* f is not installed yet. */
 struct installed_flow *i = del_f->installed_flow;
@@ -1752,6 +1772,9 @@ merge_tracked_flows(struct ovn_desired_flow_table 
*flow_table)
 ovs_assert(f->installed_flow == del_f->installed_flow);
 unlink_installed_to_desired(del_f->installed_flow, del_f);
 }
+if (del_f_was_active) {
+desired_flow_set_active(f);
+}
 hmap_remove(_flows, _f->match_hmap_node);
 ovs_list_remove(_f->track_list_node);
 desired_flow_destroy(del_f);
@@ -1779,6 +1802,7 @@ update_installed_flows_by_track(struct 
ovn_desired_flow_table *flow_table,
 /* The desired flow was deleted */
 if (f->installed_flow) {
 struct installed_flow *i = f->installed_flow;
+bool was_active = desired_flow_is_active(f);
 unlink_installed_to_desired(i, f);
 
 if (!i->desired_flow) {
@@ -1787,7 +1811,7 @@ update_installed_flows_by_track(struct 
ovn_desired_flow_table *flow_table,
 
 hmap_remove(_flows, >match_hmap_node);
 installed_flow_destroy(i);
-} else {
+} else if (was_active) {
 /* There are other desired flow(s) referencing this
  * installed flow, so update the OVS flow for the new
  * active flow (at least the cookie will be different,
@@ -1811,7 +1835,7 @@ update_installed_flows_by_track(struct 
ovn_desired_flow_table *flow_table,
 hmap_insert(_flows, _node->match_hmap_node,
 new_node->flow.hash);

[ovs-dev] [PATCH ovn branch-20.06 07/15] ofctrl.c: Avoid repeatedly linking an installed flow and a desired flow.

2021-02-18 Thread Han Zhou
In update_installed_flows_by_compare() there are two loops. The first
loop iterates the installed flows and find its peer in desired flows to:

1. uninstall flows that are not needed anymore

2. update flows if needed

At the same time, it links the desired flow found for the installed flow
which also set the desired flow as the current active installed flow.

The second loop iterates the desired flows and find its peer in installed
flows to install missing flows. At the same time it will detect if there
are conflict desired flows matching same installed flow then just link
them.

However, currently in the second loop, it blindly link the desired flows to the
installed flows, without checking if it is already linked in the first loop.
Lucky enough, this won't cause any real problem so far, because when there are
conflict flows, the one found in the first loop will be set as active in the
installed_flow, and in the function link_installed_to_desired() checks if it is
already the active desired flow it just does nothing but return.  However, the
check in the link_installed_to_desired() is confusing because a desired_flow
may be linked to the installed_flow already but not the active flow, and the
check is insufficient. It should be rather an assertion and let the caller
ensure that a pair of desired_flow and installed_flow is never linked twice.

For the above reason, this patch does the following changes:

1. Removes the check in link_installed_to_desired() and convert it to an assert.

2. Before calling link_installed_to_desired() in the above mentioned loop,
   check if the desired flow is already installed.

Acked-by: Dumitru Ceara 
Signed-off-by: Han Zhou 
(cherry picked from commit 7cab7bd1268ba67429954da4f73de91090acf779)
Signed-off-by: Frode Nordahl 
---
 controller/ofctrl.c | 19 ++-
 1 file changed, 14 insertions(+), 5 deletions(-)

diff --git a/controller/ofctrl.c b/controller/ofctrl.c
index 3225e6c67..384659d0c 100644
--- a/controller/ofctrl.c
+++ b/controller/ofctrl.c
@@ -806,13 +806,18 @@ desired_flow_set_active(struct desired_flow *d)
 d->installed_flow->desired_flow = d;
 }
 
+/* Adds the desired flow to the list of desired flows that have same match
+ * conditions as the installed flow.
+ *
+ * If the newly added desired flow is the first one in the list, it is also set
+ * as the active one.
+ *
+ * It is caller's responsibility to make sure the link between the pair didn't
+ * exist before. */
 static void
 link_installed_to_desired(struct installed_flow *i, struct desired_flow *d)
 {
-if (i->desired_flow == d) {
-return;
-}
-
+ovs_assert(i->desired_flow != d);
 if (ovs_list_is_empty(>desired_refs)) {
 ovs_assert(!i->desired_flow);
 i->desired_flow = d;
@@ -1706,8 +1711,12 @@ update_installed_flows_by_compare(struct 
ovn_desired_flow_table *flow_table,
 /* Copy 'd' from 'flow_table' to installed_flows. */
 i = installed_flow_dup(d);
 hmap_insert(_flows, >match_hmap_node, i->flow.hash);
+link_installed_to_desired(i, d);
+} else if (!d->installed_flow) {
+/* This is a desired_flow that conflicts with one installed
+ * previously but not linked yet. */
+link_installed_to_desired(i, d);
 }
-link_installed_to_desired(i, d);
 }
 }
 
-- 
2.30.0
___
dev mailing list
d...@openvswitch.org
https://mail.openvswitch.org/mailman/listinfo/ovs-dev


[ovs-dev] [PATCH ovn branch-20.06 05/15] ofctrl.c: Merge opposite changes of tracked flows before installing.

2021-02-18 Thread Han Zhou
This patch optimizes the previous patch that incrementally processes
flow installation by merging the "add-after-delete" flow changes as
much as possible to avoid unnecessary OpenFlow updates.

Acked-by: Mark Michelson 
Signed-off-by: Han Zhou 
(cherry picked from commit f4e508dd7a6cfbfc2e3250a8c11a8d0fdc1dfdd0)
Signed-off-by: Frode Nordahl 
---
 controller/ofctrl.c | 74 +
 1 file changed, 74 insertions(+)

diff --git a/controller/ofctrl.c b/controller/ofctrl.c
index b0670bf44..2d0e15978 100644
--- a/controller/ofctrl.c
+++ b/controller/ofctrl.c
@@ -1693,10 +1693,84 @@ update_installed_flows_by_compare(struct 
ovn_desired_flow_table *flow_table,
 }
 }
 
+/* Finds and returns a desired_flow in 'deleted_flows' that is exactly the
+ * same as 'target', including cookie and actions.
+ */
+static struct desired_flow *
+deleted_flow_lookup(struct hmap *deleted_flows, struct ovn_flow *target)
+{
+struct desired_flow *d;
+HMAP_FOR_EACH_WITH_HASH (d, match_hmap_node, target->hash,
+ deleted_flows) {
+struct ovn_flow *f = >flow;
+if (f->table_id == target->table_id
+&& f->priority == target->priority
+&& minimatch_equal(>match, >match)
+&& f->cookie == target->cookie
+&& ofpacts_equal(f->ofpacts, f->ofpacts_len, target->ofpacts,
+ target->ofpacts_len)) {
+return d;
+}
+}
+return NULL;
+}
+
+/* This function scans the tracked flow changes in the order and merges "add"
+ * or "update" after "deleted" operations for exactly same flow (priority,
+ * table, match, action and cookie), to avoid unnecessary OF messages being
+ * sent to OVS. */
+static void
+merge_tracked_flows(struct ovn_desired_flow_table *flow_table)
+{
+struct hmap deleted_flows = HMAP_INITIALIZER(_flows);
+struct desired_flow *f, *next;
+LIST_FOR_EACH_SAFE (f, next, track_list_node,
+_table->tracked_flows) {
+if (f->is_deleted) {
+/* reuse f->match_hmap_node field since it is already removed from
+ * the desired flow table's match index. */
+hmap_insert(_flows, >match_hmap_node,
+f->flow.hash);
+} else {
+struct desired_flow *del_f = deleted_flow_lookup(_flows,
+ >flow);
+if (!del_f) {
+continue;
+}
+
+/* del_f must have been installed, otherwise it should have been
+ * removed during track_flow_add_or_modify. */
+ovs_assert(del_f->installed_flow);
+if (!f->installed_flow) {
+/* f is not installed yet. */
+struct installed_flow *i = del_f->installed_flow;
+unlink_installed_to_desired(i, del_f);
+link_installed_to_desired(i, f);
+} else {
+/* f has been installed before, and now was updated to exact
+ * the same flow as del_f. */
+ovs_assert(f->installed_flow == del_f->installed_flow);
+unlink_installed_to_desired(del_f->installed_flow, del_f);
+}
+hmap_remove(_flows, _f->match_hmap_node);
+ovs_list_remove(_f->track_list_node);
+desired_flow_destroy(del_f);
+
+ovs_list_remove(>track_list_node);
+ovs_list_init(>track_list_node);
+}
+}
+HMAP_FOR_EACH_SAFE (f, next, match_hmap_node, _flows) {
+hmap_remove(_flows, >match_hmap_node);
+}
+hmap_destroy(_flows);
+}
+
 static void
 update_installed_flows_by_track(struct ovn_desired_flow_table *flow_table,
 struct ovs_list *msgs)
 {
+merge_tracked_flows(flow_table);
 struct desired_flow *f, *f_next;
 LIST_FOR_EACH_SAFE (f, f_next, track_list_node,
 _table->tracked_flows) {
-- 
2.30.0
___
dev mailing list
d...@openvswitch.org
https://mail.openvswitch.org/mailman/listinfo/ovs-dev


[ovs-dev] [PATCH ovn branch-20.06 04/15] ofctrl: Incremental processing for flow installation by tracking.

2021-02-18 Thread Han Zhou
With incremental processing for flow computation, the bottle neck of
ovn-controller in large scale environment is in the flow installation
(ofctrl_put()), which does full comparison between the two big flow tables: the
installed flows and desired flows.

This patch implements tracking desired flow changes when flows are
incrementally computed by I-P engine, and then incrementally processing the
flow installation using the tracked information in ofctrl_put(). It falls back
to the full comparison whenever tracking information is unavailable, e.g. when
I-P engine triggers full recompute.

In ovn-scale-test with 3000 HVs and 30k lports, the end-to-end latency between
the moment a lflow is updated in SB DB and the moment when all the 3K HVs
complete OVS flow updating has reduced around 60% (from 1s to 400ms).

Below is the perf result for a ovn-controller processing a new port-binding:

Beore:
+   96.76% 0.00%  ovn-controller  [unknown]   [k] 0x
+   90.21% 0.00%  ovn-controller  ovn-controller  [.] main
+   39.93% 1.19%  ovn-controller  ovn-controller  [.] ofctrl_put
+   31.27%12.47%  ovn-controller  ovn-controller  [.] ovn_flow_lookup
+   22.12% 3.12%  ovn-controller  ovn-controller  [.] encaps_run
+   18.69% 2.77%  ovn-controller  ovn-controller  [.] minimatch_equal
+   17.63% 4.11%  ovn-controller  ovn-controller  [.] patch_run
+   15.91% 0.00%  ovn-controller  ovn-controller  [.] 
add_bridge_mappings (inlined)
+   14.03%12.08%  ovn-controller  ovn-controller  [.] minimask_equal
+   12.41% 0.00%  ovn-controller  ovn-controller  [.] 
chassis_tunnel_add (inlined)
+   11.40% 0.00%  ovn-controller  ovn-controller  [.] tunnel_add 
(inlined)

After:
+   94.59% 0.00%  ovn-controller  [unknown]   [k] 0x
+   83.56% 0.09%  ovn-controller  ovn-controller  [.] main
+   35.37% 3.13%  ovn-controller  ovn-controller  [.] encaps_run
+   27.54% 7.53%  ovn-controller  ovn-controller  [.] patch_run
+   24.86% 0.00%  ovn-controller  ovn-controller  [.] 
add_bridge_mappings (inlined)
+   20.01% 0.00%  ovn-controller  ovn-controller  [.] 
chassis_tunnel_add (inlined)
+   18.51% 0.00%  ovn-controller  ovn-controller  [.] tunnel_add 
(inlined)
+   14.08% 0.17%  ovn-controller  ovn-controller  [.] physical_run
+   11.37%11.28%  ovn-controller  ovn-controller  [.] next_real_row
+   10.50% 2.59%  ovn-controller  ovn-controller  [.] 
consider_port_binding
..
+2.14% 0.32%  ovn-controller  ovn-controller  [.] ofctrl_put


 ▒

Before the optimization, ofctrl_put took 40% of CPU, and now it disappears from
the hot spots.

Acked-by: Mark Michelson 
Signed-off-by: Han Zhou 
(cherry picked from commit 6f0b1e02d9ab3a94048c4818f2d382938cad4b71)
Signed-off-by: Frode Nordahl 
---
 controller/ofctrl.c | 289 +++-
 controller/ofctrl.h |   6 +-
 2 files changed, 240 insertions(+), 55 deletions(-)

diff --git a/controller/ofctrl.c b/controller/ofctrl.c
index 98e291243..b0670bf44 100644
--- a/controller/ofctrl.c
+++ b/controller/ofctrl.c
@@ -101,6 +101,39 @@ struct ovn_flow {
  *
  * The links are updated whenever there is a change in desired flows, which is
  * usually triggered by a SB data change in I-P engine.
+ *
+ * ** Tracking **
+ *
+ * A desired flow can be tracked - listed in ovn_desired_flow_table's
+ * tracked_flows.
+ *
+ * Tracked flows is initially empty, and stays empty after the first run of I-P
+ * engine when installed flows are initially populated. After that, flow
+ * changes are tracked when I-P engine incrementally computes flow changes.
+ * Tracked flows are then processed and removed completely in ofctrl_put.
+ * ("processed" means OpenFlow change messages are composed and sent/queued to
+ * OVS, which ensures flows in OVS is always in sync (eventually) with the
+ * installed flows table).
+ *
+ * In case of full recompute of I-P engine, tracked flows are not
+ * added/removed, and ofctrl_put will not rely on tracked flows. (It is I-P
+ * engine's responsibility to ensure the tracked flows are cleared before
+ * recompute).
+ *
+ * Tracked flows can be preserved across multiple I-P engine runs - if in some
+ * iterations ofctrl_put() is skipped. Tracked flows are cleared only when it
+ * is consumed or when flow recompute happens.
+ *
+ * The "change_tracked" member of desired flow table maintains the status of
+ * whether flow changes are tracked or not. It is always set to true when
+ * ofctrl_put is completed, and transition to false whenever
+ * ovn_desired_flow_table_clear is called.
+ *
+ * NOTE: A tracked flow is just a reference to a desired flow, instead of a 

[ovs-dev] [PATCH ovn branch-20.06 03/15] ofctrl.c: Refactor - move openflow msg construction to functions.

2021-02-18 Thread Han Zhou
These functions will be reused in multiple places in a future patch.

Acked-by: Mark Michelson 
Signed-off-by: Han Zhou 
(cherry picked from commit 23063cf4178c05f5d6b3e4ec6d323ccc88df6101)
Signed-off-by: Frode Nordahl 
---
 controller/ofctrl.c | 103 ++--
 1 file changed, 60 insertions(+), 43 deletions(-)

diff --git a/controller/ofctrl.c b/controller/ofctrl.c
index a28c6b759..98e291243 100644
--- a/controller/ofctrl.c
+++ b/controller/ofctrl.c
@@ -1481,6 +1481,63 @@ add_meter(struct ovn_extend_table_info *m_desired,
 free(mm.meter.bands);
 }
 
+static void
+installed_flow_add(struct ovn_flow *d, struct ovs_list *msgs)
+{
+/* Send flow_mod to add flow. */
+struct ofputil_flow_mod fm = {
+.match = d->match,
+.priority = d->priority,
+.table_id = d->table_id,
+.ofpacts = d->ofpacts,
+.ofpacts_len = d->ofpacts_len,
+.new_cookie = htonll(d->cookie),
+.command = OFPFC_ADD,
+};
+add_flow_mod(, msgs);
+}
+
+static void
+installed_flow_mod(struct ovn_flow *i, struct ovn_flow *d,
+   struct ovs_list *msgs)
+{
+/* Update actions in installed flow. */
+struct ofputil_flow_mod fm = {
+.match = i->match,
+.priority = i->priority,
+.table_id = i->table_id,
+.ofpacts = d->ofpacts,
+.ofpacts_len = d->ofpacts_len,
+.command = OFPFC_MODIFY_STRICT,
+};
+/* Update cookie if it is changed. */
+if (i->cookie != d->cookie) {
+fm.modify_cookie = true;
+fm.new_cookie = htonll(d->cookie);
+/* Use OFPFC_ADD so that cookie can be updated. */
+fm.command = OFPFC_ADD;
+}
+add_flow_mod(, msgs);
+
+/* Replace 'i''s actions and cookie by 'd''s. */
+free(i->ofpacts);
+i->ofpacts = xmemdup(d->ofpacts, d->ofpacts_len);
+i->ofpacts_len = d->ofpacts_len;
+i->cookie = d->cookie;
+}
+
+static void
+installed_flow_del(struct ovn_flow *i, struct ovs_list *msgs)
+{
+struct ofputil_flow_mod fm = {
+.match = i->match,
+.priority = i->priority,
+.table_id = i->table_id,
+.command = OFPFC_DELETE_STRICT,
+};
+add_flow_mod(, msgs);
+}
+
 /* The flow table can be updated if the connection to the switch is up and
  * in the correct state and not backlogged with existing flow_mods.  (Our
  * criteria for being backlogged appear very conservative, but the socket
@@ -1606,46 +1663,16 @@ ofctrl_put(struct ovn_desired_flow_table *flow_table,
 if (!d) {
 /* Installed flow is no longer desirable.  Delete it from the
  * switch and from installed_flows. */
-struct ofputil_flow_mod fm = {
-.match = i->flow.match,
-.priority = i->flow.priority,
-.table_id = i->flow.table_id,
-.command = OFPFC_DELETE_STRICT,
-};
-add_flow_mod(, );
+installed_flow_del(>flow, );
 ovn_flow_log(>flow, "removing installed");
-
 hmap_remove(_flows, >match_hmap_node);
 installed_flow_destroy(i);
 } else {
 if (!ofpacts_equal(i->flow.ofpacts, i->flow.ofpacts_len,
d->flow.ofpacts, d->flow.ofpacts_len) ||
 i->flow.cookie != d->flow.cookie) {
-/* Update actions in installed flow. */
-struct ofputil_flow_mod fm = {
-.match = i->flow.match,
-.priority = i->flow.priority,
-.table_id = i->flow.table_id,
-.ofpacts = d->flow.ofpacts,
-.ofpacts_len = d->flow.ofpacts_len,
-.command = OFPFC_MODIFY_STRICT,
-};
-/* Update cookie if it is changed. */
-if (i->flow.cookie != d->flow.cookie) {
-fm.modify_cookie = true;
-fm.new_cookie = htonll(d->flow.cookie);
-/* Use OFPFC_ADD so that cookie can be updated. */
-fm.command = OFPFC_ADD,
-i->flow.cookie = d->flow.cookie;
-}
-add_flow_mod(, );
 ovn_flow_log(>flow, "updating installed");
-
-/* Replace 'i''s actions by 'd''s. */
-free(i->flow.ofpacts);
-i->flow.ofpacts = xmemdup(d->flow.ofpacts,
-  d->flow.ofpacts_len);
-i->flow.ofpacts_len = d->flow.ofpacts_len;
+installed_flow_mod(>flow, >flow, );
 }
 link_installed_to_desired(i, d);
 
@@ -1658,17 +1685,7 @@ ofctrl_put(struct ovn_desired_flow_table *flow_table,
 HMAP_FOR_EACH (d, match_hmap_node, _table->match_flow_table) {
 i = installed_flow_lookup(>flow);
 if (!i) {
-/* Send flow_mod to add flow. */
-struct ofputil_flow_mod fm = {
-   

[ovs-dev] [PATCH ovn branch-20.06 02/15] ofctrl.c: Maintain references between installed flows and desired flows.

2021-02-18 Thread Han Zhou
Currently there is no link maintained between installed flows and desired
flows. This patch maintains the mapping between them, which will be useful
for a future patch that incrementally processes the flow installation without
having to do the full comparison between them.

This patch also refactors the struct ovn_flow with two different wrapper
types: desired_flow and installed_flow, and the related static functions,
to make the code easier to read and avoid misuses of the struct.

Acked-by: Mark Michelson 
Signed-off-by: Han Zhou 
(cherry picked from commit 354d3853d40cbce89a434632f67daed7fc992d8b)
Signed-off-by: Frode Nordahl 
---
 controller/ofctrl.c | 428 ++--
 1 file changed, 294 insertions(+), 134 deletions(-)

diff --git a/controller/ofctrl.c b/controller/ofctrl.c
index 11832b8d7..a28c6b759 100644
--- a/controller/ofctrl.c
+++ b/controller/ofctrl.c
@@ -51,7 +51,27 @@
 
 VLOG_DEFINE_THIS_MODULE(ofctrl);
 
-/* An OpenFlow flow.
+/* An OpenFlow flow. */
+struct ovn_flow {
+/* Key. */
+uint8_t table_id;
+uint16_t priority;
+struct minimatch match;
+
+/* Hash. */
+uint32_t hash;
+
+/* Data. */
+struct ofpact *ofpacts;
+size_t ofpacts_len;
+uint64_t cookie;
+};
+
+/* A desired flow, in struct ovn_desired_flow_table, calculated by the
+ * incremental processing engine.
+ * - They are added/removed incrementally when I-P engine is able to process
+ *   the changes incrementally, or
+ * - Completely cleared and recomputed by I-P engine when recompute happens.
  *
  * Links are maintained between desired flows and SB data. The relationship
  * is M to N. The struct sb_flow_ref is used to link a pair of desired flow
@@ -82,52 +102,92 @@ VLOG_DEFINE_THIS_MODULE(ofctrl);
  * The links are updated whenever there is a change in desired flows, which is
  * usually triggered by a SB data change in I-P engine.
  */
-struct ovn_flow {
+struct desired_flow {
+struct ovn_flow flow;
 struct hmap_node match_hmap_node; /* For match based hashing. */
 struct ovs_list list_node; /* For handling lists of flows. */
-struct ovs_list references; /* A list of struct sb_flow_ref nodes, which
-   references this flow. (There are cases
-   that multiple SB entities share the same
-   desired OpenFlow flow, e.g. when
-   conjunction is used.) */
 
-/* Key. */
-uint8_t table_id;
-uint16_t priority;
-struct minimatch match;
+/* A list of struct sb_flow_ref nodes, which references this flow. (There
+ * are cases that multiple SB entities share the same desired OpenFlow
+ * flow, e.g. when conjunction is used.) */
+struct ovs_list references;
 
-/* Data. */
-struct ofpact *ofpacts;
-size_t ofpacts_len;
-uint64_t cookie;
+/* The corresponding flow in installed table. */
+struct installed_flow *installed_flow;
+
+/* Node in installed_flow.desired_refs list. */
+struct ovs_list installed_ref_list_node;
 };
 
 struct sb_to_flow {
 struct hmap_node hmap_node; /* Node in
ovn_desired_flow_table.uuid_flow_table. */
 struct uuid sb_uuid;
-struct ovs_list flows; /* A list of struct sb_flow_ref nodes that are
-  referenced by the sb_uuid. */
+struct ovs_list flows; /* A list of struct sb_flow_ref nodes that
+  are referenced by the sb_uuid. */
 };
 
 struct sb_flow_ref {
-struct ovs_list sb_list; /* List node in ovn_flow.references. */
-struct ovs_list flow_list; /* List node in sb_to_flow.ovn_flows. */
-struct ovn_flow *flow;
+struct ovs_list sb_list; /* List node in desired_flow.references. */
+struct ovs_list flow_list; /* List node in sb_to_flow.desired_flows. */
+struct desired_flow *flow;
 struct uuid sb_uuid;
 };
 
-static struct ovn_flow *ovn_flow_alloc(uint8_t table_id, uint16_t priority,
-   uint64_t cookie,
-   const struct match *match,
-   const struct ofpbuf *actions);
+/* A installed flow, in static variable installed_flows.
+ *
+ * Installed flows are updated in ofctrl_put for maintaining the flow
+ * installation to OVS. They are updated according to desired flows: either by
+ * processing the tracked desired flow changes, or by comparing desired flows
+ * with currently installed flows when tracked desired flows changes are not
+ * available.
+ *
+ * In addition, when ofctrl state machine enters S_CLEAR, the installed flows
+ * will be cleared. (This happens in initialization phase and also when
+ * ovs-vswitchd is disconnected/reconnected).
+ *
+ * Links are maintained between installed flows and desired flows. The
+ * relationship is 1 to N. A link is added when a flow addition is processed.
+ * A 

[ovs-dev] [PATCH ovn branch-20.06 01/15] ovn-ctl: Handle cluster db upgrades for run_(nb/sb)_ovsdb

2021-02-18 Thread Numan Siddique
when ovn-ctl run_(nb_sb)_ovsdb is called, the ovsdb-server is started without
passing --detach and --monoitor and the process is exec'd.

For cluster mode, upgrade_cluster is never called and hence the dbs are not 
upraded
to new schema. CMS has to handle the db upgrade separately.

This patch handles the db upgrade by starting ovsdb-server in background and 
then
waits on ovsdb-server to complete.

Reported-at: https://bugzilla.redhat.com/show_bug.cgi?id=1868392
Acked-by: Mark Michelson 
Signed-off-by: Numan Siddique 
(cherry picked from commit 67e2f386cc838d0b0f9b4b5da7fe611e1113b70c)
Signed-off-by: Frode Nordahl 
---
 utilities/ovn-ctl | 20 +++-
 1 file changed, 19 insertions(+), 1 deletion(-)

diff --git a/utilities/ovn-ctl b/utilities/ovn-ctl
index 8afe68a0a..ad8e6bb04 100755
--- a/utilities/ovn-ctl
+++ b/utilities/ovn-ctl
@@ -288,7 +288,21 @@ $cluster_remote_port
 set "$@" --sync-from=`cat $active_conf_file`
 fi
 
-"$@" "$file"
+local run_ovsdb_in_bg="no"
+local process_id=
+if test X$detach = Xno && test $mode = cluster && test -z 
"$cluster_remote_addr" ; then
+# When detach is no (for run_nb_ovsdb/run_sb_ovsdb commands)
+# we want to run ovsdb-server in background rather than running it in
+# foreground so that the OVN dbs are upgraded for the cluster mode.
+# Otherwise, CMS has to take the responsibility of upgrading the dbs.
+# Note: We run only the ovsdb-server in backgroud which created the
+# cluster (i.e cluster_remote_addr is not set.).
+run_ovsdb_in_bg="yes"
+"$@" $file &
+process_id=$!
+else
+start_wrapped_daemon "$wrapper" ovsdb-$db "" "$@" "$file"
+fi
 
 # Initialize the database if it's NOT joining a cluster.
 if test -z "$cluster_remote_addr"; then
@@ -298,6 +312,10 @@ $cluster_remote_port
 if test $mode = cluster; then
 upgrade_cluster "$schema" "unix:$sock"
 fi
+
+if test $run_ovsdb_in_bg = yes; then
+wait $process_id
+fi
 }
 
 start_nb_ovsdb() {
-- 
2.30.0
___
dev mailing list
d...@openvswitch.org
https://mail.openvswitch.org/mailman/listinfo/ovs-dev


[ovs-dev] [PATCH ovn branch-20.06 00/15] Backport rollup

2021-02-18 Thread Frode Nordahl
Hello all,

In Ubuntu we have backported a set of fixes to our OVN 20.06 and OVN
20.03 packages.  In preparing for new point releases for OVN 20.06
and OVN 20.03, we would very much like to add these patches to the
upstream branches.

The issues solved for OVN 20.06 with these patches are:

  * Fix for upgrading database schema of clustered databases on package
upgrade (LP: #1907081)[0]
  * Fixes for predictable resolution for conflicting flow actions.
(LP: #1906922)[1]

We are cognizant of the large number of patches required to cleanly
backport the conflicting flow actions fixes, and have verified the end
result thouroughly. From our experience these fixes are required to use
OVN with OpenStack in a meaningful way, for example with k8s on top of
OpenStack.

0: https://bugs.launchpad.net/bugs/1907081
1: https://bugs.launchpad.net/bugs/1906922

Dumitru Ceara (8):
  ofctrl.c: Only merge actions for conjunctive flows.
  ofctrl.c: Do not change flow ordering when merging opposite changes.
  ofctrl.c: Simplify active desired flow selection.
  ofctrl.c: Always log the most recent flow changes.
  ofctrl.c: Add a predictable resolution for conflicting flow actions.
  ovn.at: Make some of the tests more predictable.
  tests: Add ofctl_strip_all() to filter OVS flow outputs.
  tests: Fix test "ovn -- Superseding ACLs with conjunction".

Han Zhou (6):
  ofctrl.c: Maintain references between installed flows and desired
flows.
  ofctrl.c: Refactor - move openflow msg construction to functions.
  ofctrl: Incremental processing for flow installation by tracking.
  ofctrl.c: Merge opposite changes of tracked flows before installing.
  ofctrl.c: Fix duplicated flow handling in I-P while merging opposite
changes.
  ofctrl.c: Avoid repeatedly linking an installed flow and a desired
flow.

Numan Siddique (1):
  ovn-ctl: Handle cluster db upgrades for run_(nb/sb)_ovsdb

 controller/ofctrl.c | 966 
 controller/ofctrl.h |   6 +-
 tests/ofproto-macros.at |  23 +-
 tests/ovn.at| 328 ++
 utilities/ovn-ctl   |  20 +-
 5 files changed, 1156 insertions(+), 187 deletions(-)

-- 
2.30.0
___
dev mailing list
d...@openvswitch.org
https://mail.openvswitch.org/mailman/listinfo/ovs-dev