Re: [ovs-dev] [PATCH ovn] northd: Update virtual port when updating parent ports.

2024-07-25 Thread Mohammad Heib
Hi Ilya,
Thank you for your quick review

On Thu, Jul 25, 2024 at 12:00 AM Ilya Maximets  wrote:

> On 7/24/24 11:56, Mohammad Heib wrote:
> > Northd will not update/add flows for a virtual port if their
> > parent ports were created/recreated after creating this virtual port.
> >
> > This change will fix the above issue by triggering an update for a
> > virtual port if their parent port has been created.
> >
> > Rreported-at: https://issues.redhat.com/browse/FDP-710
> > Signed-off-by: Mohammad Heib 
> > ---
> >  northd/northd.c | 19 ++-
> >  tests/ovn.at| 84 +
> >  2 files changed, 102 insertions(+), 1 deletion(-)
> >
>
> Hi, Mohammad.  Thanks for the patch!
> See some comments inline.
>
> > diff --git a/northd/northd.c b/northd/northd.c
> > index 5b50ea191..39c19b07f 100644
> > --- a/northd/northd.c
> > +++ b/northd/northd.c
> > @@ -4524,7 +4524,7 @@ ls_handle_lsp_changes(struct ovsdb_idl_txn
> *ovnsb_idl_txn,
> >  bool ls_had_only_router_ports = (od->n_router_ports
> >  && (od->n_router_ports == hmap_count(>ports)));
> >
> > -struct ovn_port *op;
> > +struct ovn_port *op, *op_v;
> >  HMAP_FOR_EACH (op, dp_node, >ports) {
> >  op->visited = false;
> >  }
> > @@ -4547,6 +4547,23 @@ ls_handle_lsp_changes(struct ovsdb_idl_txn
> *ovnsb_idl_txn,
> >  goto fail;
> >  }
> >  add_op_to_northd_tracked_ports(_lsps->created, op);
> > +
> > +/*
> > + * Update old virtual ports that had this VIF as parent port
> > + * this code handles cases where the virtual port was
> created
> > + * before the parent port or when the parent port was
> recreated.
> > + */
> > +if (!strcmp(new_nbsp->type, "")) {
> > +for (size_t i = 0; i < changed_ls->n_ports; i++) {
>
> This seems inefficient and may potentially tank performance at scale.
> There should be a way to find all these ports without introducing
> quadratic complexity.
>

yes, I agree that code is inefficient.

>
> On option might be to iterate once, if trk_lsps->created is not empty
> after the loop, find all the parent ports and check if they are in
> trk_lsps->created.
>

if you please can take a look at v2
<https://patchwork.ozlabs.org/project/ovn/patch/20240725072049.3884358-1-mh...@redhat.com/>,
 i adopted your idea with some changes.
First, i will save all existing virtual ports during the first loop, these
ports are already exist so no need to check
if they are in both updated and created lists.
afterward, at the end of the function, i will go through all the found
virtual ports and for each vport i will check if one of the newly created
port is a parent, and if so i will add it to the update list.
worst case scenario complexity will be: Number of existing virtual ports *
the number of newly created ports.
 which i think is the best i can do :(.


>
> Not sure if that's the most efficient way, but seems better than
> quadratic.  What do you think?
>
> > +op_v = ovn_port_find_in_datapath(od,
> changed_ls->ports[i]);
> > +if (op_v && !strcmp(op_v->nbsp->type, "virtual") &&
> > +strstr(smap_get_def(_v->nbsp->options,
> > +   "virtual-parents", ""), new_nbsp->name))
> {
> > +
> add_op_to_northd_tracked_ports(_lsps->updated,
> > +   op_v);
>
> Is there a chance that these ports end up in both updated and created?
> Can this cause issues later?
>
> Best regards, Ilya Maximets.
>
>
___
dev mailing list
d...@openvswitch.org
https://mail.openvswitch.org/mailman/listinfo/ovs-dev


[ovs-dev] [PATCH ovn v2] northd: Update virtual port when updating parent ports.

2024-07-25 Thread Mohammad Heib
Northd will not update/add flows for a virtual port if their
parent ports were created/recreated after creating this virtual port.

This change will fix the above issue by triggering an update for a
virtual port if their parent port has been created.

Rreported-at: https://issues.redhat.com/browse/FDP-710
Signed-off-by: Mohammad Heib 
---
 northd/northd.c | 28 +
 tests/ovn.at| 84 +
 2 files changed, 112 insertions(+)

diff --git a/northd/northd.c b/northd/northd.c
index 5b50ea191..0db0ba006 100644
--- a/northd/northd.c
+++ b/northd/northd.c
@@ -4525,6 +4525,8 @@ ls_handle_lsp_changes(struct ovsdb_idl_txn *ovnsb_idl_txn,
 && (od->n_router_ports == hmap_count(>ports)));
 
 struct ovn_port *op;
+struct ovs_list exist_virtual_ports;
+ovs_list_init(_virtual_ports);
 HMAP_FOR_EACH (op, dp_node, >ports) {
 op->visited = false;
 }
@@ -4588,6 +4590,8 @@ ls_handle_lsp_changes(struct ovsdb_idl_txn *ovnsb_idl_txn,
 delete_fdb_entry(ni->sbrec_fdb_by_dp_and_port, od->tunnel_key,
  old_tunnel_key);
 }
+} else if (!strcmp(op->nbsp->type, "virtual")) {
+ovs_list_push_back(_virtual_ports, >list);
 }
 op->visited = true;
 }
@@ -4628,6 +4632,30 @@ ls_handle_lsp_changes(struct ovsdb_idl_txn 
*ovnsb_idl_txn,
 }
 }
 
+/*
+ * Update old virtual ports that have new created VIF as parent port
+ * this code handles cases where the virtual port was created
+ * before the parent port or when the parent port was recreated.
+ */
+ if (!ovs_list_is_empty(_virtual_ports)) {
+ struct hmapx_node *hmapx_node;
+ struct ovn_port *new_op;
+ LIST_FOR_EACH (op, list, _virtual_ports) {
+ ovs_list_remove(>list);
+ HMAPX_FOR_EACH (hmapx_node, _lsps->created) {
+ new_op = hmapx_node->data;
+ if (strstr(smap_get_def(>nbsp->options,
+ "virtual-parents", ""), new_op->nbsp->name)) {
+ add_op_to_northd_tracked_ports(_lsps->updated, op);
+ /* Can stop the loop cause we have at lest one new parent
+  * created, no need to check the rest.
+  */
+ break;
+ }
+ }
+ }
+ }
+
 return true;
 
 fail:
diff --git a/tests/ovn.at b/tests/ovn.at
index 2ced7c0b2..83fba4f11 100644
--- a/tests/ovn.at
+++ b/tests/ovn.at
@@ -22439,6 +22439,90 @@ OVN_CLEANUP([hv1], [hv2])
 AT_CLEANUP
 ])
 
+OVN_FOR_EACH_NORTHD([
+AT_SETUP([virtual port - parents port re-create])
+AT_KEYWORDS([virtual ports])
+ovn_start
+send_garp() {
+local hv=$1 inport=$2 eth_src=$3 eth_dst=$4 spa=$5 tpa=$6
+local 
request=${eth_dst}${eth_src}08060001080006040001${eth_src}${spa}${eth_dst}${tpa}
+as hv$hv ovs-appctl netdev-dummy/receive hv${hv}-vif$inport $request
+}
+
+net_add n1
+
+sim_add hv1
+as hv1
+ovs-vsctl add-br br-phys
+ovn_attach n1 br-phys 192.168.0.1
+ovn-appctl vlog/set dbg
+ovs-vsctl -- add-port br-int hv1-vif1 -- \
+set interface hv1-vif1 external-ids:iface-id=sw0-p1 \
+options:tx_pcap=hv1/vif1-tx.pcap \
+options:rxq_pcap=hv1/vif1-rx.pcap \
+ofport-request=1
+
+ovs-appctl -t ovn-controller vlog/set dbg
+
+ovn-nbctl ls-add sw0
+check ovn-nbctl lsp-add sw0 sw0-p1
+check ovn-nbctl lsp-set-addresses sw0-p1 "50:54:00:00:00:03 10.0.0.3 1000::3"
+check ovn-nbctl lsp-set-port-security sw0-p1 "50:54:00:00:00:03 10.0.0.3 
10.0.0.10 1000::3"
+
+check ovn-nbctl lsp-add sw0 sw0-vir
+check ovn-nbctl lsp-set-addresses sw0-vir "50:54:00:00:00:10 10.0.0.10"
+check ovn-nbctl lsp-set-port-security sw0-vir "50:54:00:00:00:10 10.0.0.10"
+check ovn-nbctl lsp-set-type sw0-vir virtual
+check ovn-nbctl set logical_switch_port sw0-vir options:virtual-ip=10.0.0.10
+check ovn-nbctl set logical_switch_port sw0-vir options:virtual-parents=sw0-p1
+
+wait_for_ports_up
+ovn-nbctl --wait=hv sync
+hv1_ch_uuid=`ovn-sbctl --bare --columns _uuid find chassis name="hv1"`
+
+# From sw0-p1 send GARP for 10.0.0.10. hv1 should claim sw0-vir
+# and sw0-p1 should be its virtual_parent.
+eth_src=50540003
+eth_dst=
+spa=$(ip_to_hex 10 0 0 10)
+tpa=$(ip_to_hex 10 0 0 10)
+send_garp 1 1 $eth_src $eth_dst $spa $tpa
+
+OVS_WAIT_UNTIL([test 1 = `cat hv1/ovn-controller.log | grep "pinctrl received  
packet-in" | \
+grep opcode=BIND_VPORT | grep OF_Table_ID=$(ovn-debug lflow-stage-to-oftable 
ls_in_arp_rsp) | wc -l`])
+wait_row_count Port_Binding 1 logical_port=sw0-vir chassis=$hv1_ch_uuid
+check_row_count Port_Binding 1 logical_port=sw0-vir virtual_parent=sw0-p1
+wait_for_ports_up sw0-vir
+
+# Delete parent port
+check ovn-nbctl lsp-del sw0-p1
+ovn-nbctl --wait=hv sync
+
+

[ovs-dev] [PATCH ovn] northd: Update virtual port when updating parent ports.

2024-07-24 Thread Mohammad Heib
Northd will not update/add flows for a virtual port if their
parent ports were created/recreated after creating this virtual port.

This change will fix the above issue by triggering an update for a
virtual port if their parent port has been created.

Rreported-at: https://issues.redhat.com/browse/FDP-710
Signed-off-by: Mohammad Heib 
---
 northd/northd.c | 19 ++-
 tests/ovn.at| 84 +
 2 files changed, 102 insertions(+), 1 deletion(-)

diff --git a/northd/northd.c b/northd/northd.c
index 5b50ea191..39c19b07f 100644
--- a/northd/northd.c
+++ b/northd/northd.c
@@ -4524,7 +4524,7 @@ ls_handle_lsp_changes(struct ovsdb_idl_txn *ovnsb_idl_txn,
 bool ls_had_only_router_ports = (od->n_router_ports
 && (od->n_router_ports == hmap_count(>ports)));
 
-struct ovn_port *op;
+struct ovn_port *op, *op_v;
 HMAP_FOR_EACH (op, dp_node, >ports) {
 op->visited = false;
 }
@@ -4547,6 +4547,23 @@ ls_handle_lsp_changes(struct ovsdb_idl_txn 
*ovnsb_idl_txn,
 goto fail;
 }
 add_op_to_northd_tracked_ports(_lsps->created, op);
+
+/*
+ * Update old virtual ports that had this VIF as parent port
+ * this code handles cases where the virtual port was created
+ * before the parent port or when the parent port was recreated.
+ */
+if (!strcmp(new_nbsp->type, "")) {
+for (size_t i = 0; i < changed_ls->n_ports; i++) {
+op_v = ovn_port_find_in_datapath(od, changed_ls->ports[i]);
+if (op_v && !strcmp(op_v->nbsp->type, "virtual") &&
+strstr(smap_get_def(_v->nbsp->options,
+   "virtual-parents", ""), new_nbsp->name)) {
+add_op_to_northd_tracked_ports(_lsps->updated,
+   op_v);
+}
+}
+}
 } else if (ls_port_has_changed(new_nbsp)) {
 /* Existing port updated */
 bool temp = false;
diff --git a/tests/ovn.at b/tests/ovn.at
index 13b393932..93774b717 100644
--- a/tests/ovn.at
+++ b/tests/ovn.at
@@ -22439,6 +22439,90 @@ OVN_CLEANUP([hv1], [hv2])
 AT_CLEANUP
 ])
 
+OVN_FOR_EACH_NORTHD([
+AT_SETUP([virtual port - parents port re-create])
+AT_KEYWORDS([virtual ports])
+ovn_start
+send_garp() {
+local hv=$1 inport=$2 eth_src=$3 eth_dst=$4 spa=$5 tpa=$6
+local 
request=${eth_dst}${eth_src}08060001080006040001${eth_src}${spa}${eth_dst}${tpa}
+as hv$hv ovs-appctl netdev-dummy/receive hv${hv}-vif$inport $request
+}
+
+net_add n1
+
+sim_add hv1
+as hv1
+ovs-vsctl add-br br-phys
+ovn_attach n1 br-phys 192.168.0.1
+ovn-appctl vlog/set dbg
+ovs-vsctl -- add-port br-int hv1-vif1 -- \
+set interface hv1-vif1 external-ids:iface-id=sw0-p1 \
+options:tx_pcap=hv1/vif1-tx.pcap \
+options:rxq_pcap=hv1/vif1-rx.pcap \
+ofport-request=1
+
+ovs-appctl -t ovn-controller vlog/set dbg
+
+ovn-nbctl ls-add sw0
+check ovn-nbctl lsp-add sw0 sw0-p1
+check ovn-nbctl lsp-set-addresses sw0-p1 "50:54:00:00:00:03 10.0.0.3 1000::3"
+check ovn-nbctl lsp-set-port-security sw0-p1 "50:54:00:00:00:03 10.0.0.3 
10.0.0.10 1000::3"
+
+check ovn-nbctl lsp-add sw0 sw0-vir
+check ovn-nbctl lsp-set-addresses sw0-vir "50:54:00:00:00:10 10.0.0.10"
+check ovn-nbctl lsp-set-port-security sw0-vir "50:54:00:00:00:10 10.0.0.10"
+check ovn-nbctl lsp-set-type sw0-vir virtual
+check ovn-nbctl set logical_switch_port sw0-vir options:virtual-ip=10.0.0.10
+check ovn-nbctl set logical_switch_port sw0-vir options:virtual-parents=sw0-p1
+
+wait_for_ports_up
+ovn-nbctl --wait=hv sync
+hv1_ch_uuid=`ovn-sbctl --bare --columns _uuid find chassis name="hv1"`
+
+# From sw0-p1 send GARP for 10.0.0.10. hv1 should claim sw0-vir
+# and sw0-p1 should be its virtual_parent.
+eth_src=50540003
+eth_dst=
+spa=$(ip_to_hex 10 0 0 10)
+tpa=$(ip_to_hex 10 0 0 10)
+send_garp 1 1 $eth_src $eth_dst $spa $tpa
+
+OVS_WAIT_UNTIL([test 1 = `cat hv1/ovn-controller.log | grep "pinctrl received  
packet-in" | \
+grep opcode=BIND_VPORT | grep OF_Table_ID=$(ovn-debug lflow-stage-to-oftable 
ls_in_arp_rsp) | wc -l`])
+wait_row_count Port_Binding 1 logical_port=sw0-vir chassis=$hv1_ch_uuid
+check_row_count Port_Binding 1 logical_port=sw0-vir virtual_parent=sw0-p1
+wait_for_ports_up sw0-vir
+
+# Delete parent port
+check ovn-nbctl lsp-del sw0-p1
+ovn-nbctl --wait=hv sync
+
+# Re-add parent port
+check ovn-nbctl lsp-add sw0 sw0-p1
+check ovn-nbctl lsp-set-addresses sw0-p1 "50:54:00:00:00:03 10.0.0.3 1000::3"
+check ovn-nbctl lsp-set-port-security sw0-p1 "50:54:00:00:00:03 10.0.0.3 
10.0.0.10 1000::3"
+
+wait_for_ports_up
+# From sw0-p1 send GARP for 

Re: [ovs-dev] [PATCH ovn 3/4] Revert "northd: Don't skip transit switch LSP when creating mcast groups."

2024-06-18 Thread Mohammad Heib
On Tue, Jun 18, 2024 at 4:32 PM Dumitru Ceara  wrote:

> This reverts commit 85ca2b75369c9a73f4750d5914666a54ebb3f2e0.
>
> The commit above breaks inter-AZ IP multicast for the case when one of
> the multicast receivers is co-located in the same zone as the sender.
> In those cases traffic is not correctly forwarded to other receivers
> that joined the group in other AZs.
>
> This is often the case in ovn-kubernetes deployments (with IC enabled).
> The current "interconnection - IGMP/MLD multicast" unit test failed to
> cover such topologies.
>
> CC: Mohammad Heib 
> Fixes: 85ca2b75369c ("northd: Don't skip transit switch LSP when creating
> mcast groups.")
> Reported-at: https://issues.redhat.com/browse/FDP-656
> Signed-off-by: Dumitru Ceara 
> ---
>  northd/northd.c |  8 +++-
>  northd/northd.h |  6 --
>  tests/ovn-ic.at | 10 --
>  3 files changed, 3 insertions(+), 21 deletions(-)
>
> diff --git a/northd/northd.c b/northd/northd.c
> index 3c1affb02f..7e474a7b89 100644
> --- a/northd/northd.c
> +++ b/northd/northd.c
> @@ -5434,13 +5434,11 @@ ovn_igmp_group_get_ports(const struct
> sbrec_igmp_group *sb_igmp_group,
>  continue;
>  }
>
> -/* If this is already a port of a router on which relay is enabled
> - * and it's not a transit switch to router port, skip it for the
> - * group.  Traffic is flooded there anyway.
> +/* If this is already a port of a router on which relay is
> enabled,
> + * skip it for the group. Traffic is flooded there anyway.
>   */
>  if (port->peer && port->peer->od &&
> -port->peer->od->mcast_info.rtr.relay &&
> -!ovn_datapath_is_transit_switch(port->od)) {
> +port->peer->od->mcast_info.rtr.relay) {
>  continue;
>  }
>
> diff --git a/northd/northd.h b/northd/northd.h
> index 146139bebc..fd884c851e 100644
> --- a/northd/northd.h
> +++ b/northd/northd.h
> @@ -362,12 +362,6 @@ ovn_datapath_is_stale(const struct ovn_datapath *od)
>  return !od->nbr && !od->nbs;
>  };
>
> -static inline bool
> -ovn_datapath_is_transit_switch(const struct ovn_datapath *od)
> -{
> -return od->tunnel_key >= OVN_MIN_DP_KEY_GLOBAL;
> -}
> -
>  /* Pipeline stages. */
>
>  /* The two purposes for which ovn-northd uses OVN logical datapaths. */
> diff --git a/tests/ovn-ic.at b/tests/ovn-ic.at
> index 1666e77295..20409f70ac 100644
> --- a/tests/ovn-ic.at
> +++ b/tests/ovn-ic.at
> @@ -2042,20 +2042,10 @@ wait_row_count IGMP_Group 2 address=239.0.1.68
>  wait_row_count IGMP_Group 2 address='"ff0a:dead:beef::1"'
>  check ovn-nbctl --wait=hv sync
>
> -#Validate that Multicast Group contains all registered ports for
> -# specific igmp group.
> -ts_dp=$(fetch_column datapath_binding _uuid external_ids:name=ts)
> -ports=$(fetch_column multicast_group ports name="239.0.1.68"
> datapath=$ts_dp)
> -check test X2 = X$(echo $ports | wc -w)
> -
> -
>  ovn_as az2
>  wait_row_count IGMP_Group 2 address=239.0.1.68
>  wait_row_count IGMP_Group 2 address='"ff0a:dead:beef::1"'
>  check ovn-nbctl --wait=hv sync
> -ts_dp=$(fetch_column datapath_binding _uuid external_ids:name=ts)
> -ports=$(fetch_column multicast_group ports name="239.0.1.68"
> datapath=$ts_dp)
> -check test X2 = X$(echo $ports | wc -w)
>
>  # Send an IP multicast packet from LSP2, it should be forwarded
>  # to lsp1 and lsp3.
> --
> 2.44.0
>
>
looks good to me, thanks Dumitru.

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


Re: [ovs-dev] [PATCH ovn 1/4] Revert "IC: Tansit switch don't flood mcast traffic to router ports if matches igmp group."

2024-06-18 Thread Mohammad Heib
Acked-by: Mohammad Heib 

Thanks

On Tue, Jun 18, 2024 at 4:42 PM 0-day Robot  wrote:

> Bleep bloop.  Greetings Dumitru Ceara, 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: The subject, ': ', is over 70 characters, i.e., 91.
> WARNING: The subject summary should end with a dot.
> Subject: Revert "IC: Tansit switch don't flood mcast traffic to router
> ports if matches igmp group."
> Lines checked: 90, Warnings: 2, 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
>
>
___
dev mailing list
d...@openvswitch.org
https://mail.openvswitch.org/mailman/listinfo/ovs-dev


[ovs-dev] [PATCH ovn 2/2] IC: Tansit switch don't flood mcast traffic to router ports if matches igmp group.

2024-03-15 Thread Mohammad Heib
Crrently ovn transit switch forward mcast traffic that match an igmp
group to all ports participating in this group and to all router ports
that are connected to this TS switch and have mcast_flood enabled.

The above behavior can lead to packet duplicate if we have a VM in
a specific AZ that participates in igmp group because the gateway router
in this AZ will forward igmp membership report from the VM to the TS
which will be learned as an IGMP_group on the Tansit switch in different
AZs and every mcast traffic to that igmp group address from the different
AZs will be handled by the Tansit switch twice:
 - First time TS will send the traffic according to the igmp group
   which will reach the VM.

 - Second time TS will send the traffic to all router ports including
   the router that exists on the VM AZ which will forward the traffic
   to the VM again.

To avoid this issue this patch adds flows that forward mcast traffic
that match igmp group to the igmp group ports only, this flows only
apply to Transit switches.

Rreported-at: https://issues.redhat.com/browse/FDP-101
Signed-off-by: Mohammad Heib 
---
 northd/northd.c | 18 ++
 northd/ovn-northd.8.xml |  7 +++
 2 files changed, 21 insertions(+), 4 deletions(-)

diff --git a/northd/northd.c b/northd/northd.c
index 98c837a20..0c5122d27 100644
--- a/northd/northd.c
+++ b/northd/northd.c
@@ -9362,8 +9362,14 @@ build_lswitch_destination_lookup_bmcast(struct 
ovn_datapath *od,
 }
 
 
-/* Ingress table 25: Add IP multicast flows learnt from IGMP/MLD
- * (priority 90). */
+/* Ingress table 27: Add IP multicast flows learnt from IGMP/MLD
+ * (priority 90).
+ *
+ * Ingress table 27: Transit switch add IP multicast flows learnt
+ * from IGMP/MLD to forward traffic explicitly to the ports that are
+ * part of the IGMP/MLD group, and ignore MROUTERAS Ports.
+ * (priority 95).
+ */
 static void
 build_lswitch_ip_mcast_igmp_mld(struct ovn_igmp_group *igmp_group,
 struct lflow_table *lflows,
@@ -9377,6 +9383,9 @@ build_lswitch_ip_mcast_igmp_mld(struct ovn_igmp_group 
*igmp_group,
 ds_clear(match);
 ds_clear(actions);
 
+bool transit_switch =
+ovn_datapath_is_transit_switch(igmp_group->datapath);
+
 struct mcast_switch_info *mcast_sw_info =
 _group->datapath->mcast_info.sw;
 uint64_t table_size = mcast_sw_info->table_size;
@@ -9422,7 +9431,7 @@ build_lswitch_ip_mcast_igmp_mld(struct ovn_igmp_group 
*igmp_group,
 }
 
 /* Also flood traffic to all multicast routers with relay enabled. */
-if (mcast_sw_info->flood_relay) {
+if (mcast_sw_info->flood_relay && !transit_switch) {
 ds_put_cstr(actions,
 "clone { "
 "outport = \""MC_MROUTER_FLOOD "\"; "
@@ -9440,7 +9449,8 @@ build_lswitch_ip_mcast_igmp_mld(struct ovn_igmp_group 
*igmp_group,
   igmp_group->mcgroup.name);
 
 ovn_lflow_add(lflows, igmp_group->datapath, S_SWITCH_IN_L2_LKUP,
-  90, ds_cstr(match), ds_cstr(actions), NULL);
+  transit_switch? 95 : 90, ds_cstr(match),
+  ds_cstr(actions), NULL);
 }
 }
 
diff --git a/northd/ovn-northd.8.xml b/northd/ovn-northd.8.xml
index 17b414144..e25285d67 100644
--- a/northd/ovn-northd.8.xml
+++ b/northd/ovn-northd.8.xml
@@ -1933,6 +1933,13 @@ output;
 logical switch.
   
 
+  
+Priority-95 flows for transit switches only that forward registered
+IP multicast traffic to their corresponding multicast group , which
+ovn-northd creates based on learnt
+ entries.
+  
+
   
 Priority-90 flows that forward registered IP multicast traffic to
 their corresponding multicast group, which ovn-northd
-- 
2.34.3

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


[ovs-dev] [PATCH ovn 1/2] northd: Don't skip transit switch LSP when creating mcast groups.

2024-03-15 Thread Mohammad Heib
Currently when we enable IGMP on OVN-IC cluster with two or more AZs
and one vm from AZ1 send IGMP report, northd will create the following
multicast_group on each AZ:

AZ1:
 1. multicast_group that forward the mcast traffic from LS1 to the VM.
 2. multicast_group that forward the mcast traffic from LR1 to the LS1.

AZ2:
 1. multicast_group that forward the mcast traffic from TS to LR1 in
AZ1.

This design works fine if we have one logical network only on each AZ,
but if we have two or more logical network on the same AZ that separated
from each other and only connected via transit switch and both join the
same mcast network, the traffic will be delivered between those two
networks because ovn floods it to all routers that connected to the
transit switch (see logical flow table 27).

The above design is not the right way to handle such mcast traffic
because future changes for ovn that make it match explicitly on the igmp
group address and not forward traffic to routers can break the mcast
traffic in ovn-ic.

This patch updates the above design by adding the router port that
connects to the transit switch to the multicast_group even if the peer
port have mcast_flood enabled.

Signed-off-by: Mohammad Heib 
---
 northd/northd.c |  8 +---
 northd/northd.h |  6 ++
 tests/ovn.at| 10 ++
 3 files changed, 21 insertions(+), 3 deletions(-)

diff --git a/northd/northd.c b/northd/northd.c
index 1839b7d8b..98c837a20 100644
--- a/northd/northd.c
+++ b/northd/northd.c
@@ -5377,11 +5377,13 @@ ovn_igmp_group_get_ports(const struct sbrec_igmp_group 
*sb_igmp_group,
 continue;
 }
 
-/* If this is already a port of a router on which relay is enabled,
- * skip it for the group. Traffic is flooded there anyway.
+/* If this is already a port of a router on which relay is enabled
+ * and it's not a transit switch to router port,skip it for the group.
+ * Traffic is flooded there anyway.
  */
 if (port->peer && port->peer->od &&
-port->peer->od->mcast_info.rtr.relay) {
+port->peer->od->mcast_info.rtr.relay &&
+!ovn_datapath_is_transit_switch(port->od)) {
 continue;
 }
 
diff --git a/northd/northd.h b/northd/northd.h
index 3f1cd8341..5e9fa4745 100644
--- a/northd/northd.h
+++ b/northd/northd.h
@@ -362,6 +362,12 @@ ovn_datapath_is_stale(const struct ovn_datapath *od)
 return !od->nbr && !od->nbs;
 };
 
+static inline bool
+ovn_datapath_is_transit_switch(const struct ovn_datapath *od)
+{
+return od->tunnel_key >= OVN_MIN_DP_KEY_GLOBAL;
+}
+
 /* Pipeline stages. */
 
 /* The two purposes for which ovn-northd uses OVN logical datapaths. */
diff --git a/tests/ovn.at b/tests/ovn.at
index 438c7690a..4a9e433b2 100644
--- a/tests/ovn.at
+++ b/tests/ovn.at
@@ -26903,10 +26903,20 @@ wait_row_count IGMP_Group 2 address=239.0.1.68
 wait_row_count IGMP_Group 2 address='"ff0a:dead:beef::1"'
 check ovn-nbctl --wait=hv sync
 
+#Validate that Multicast Group contains all registered ports for
+# specific igmp group.
+ts_dp=$(fetch_column datapath_binding _uuid external_ids:name=ts)
+ports=$(fetch_column multicast_group ports name="239.0.1.68" datapath=$ts_dp)
+check test X2 = X$(echo $ports | wc -w)
+
+
 ovn_as az2
 wait_row_count IGMP_Group 2 address=239.0.1.68
 wait_row_count IGMP_Group 2 address='"ff0a:dead:beef::1"'
 check ovn-nbctl --wait=hv sync
+ts_dp=$(fetch_column datapath_binding _uuid external_ids:name=ts)
+ports=$(fetch_column multicast_group ports name="239.0.1.68" datapath=$ts_dp)
+check test X2 = X$(echo $ports | wc -w)
 
 # Send an IP multicast packet from LSP2, it should be forwarded
 # to lsp1 and lsp3.
-- 
2.34.3

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


Re: [ovs-dev] [RFC ovn] ovn-ic: avoid igmp/mld traffic flooding

2024-03-15 Thread Mohammad Heib
Hi Lorenzo,

i have applied and tested this change and i can confirm that it fixes the
issue.
if you please can rebase on top of the main.


Acked-by: Mohammad Heib 

On Thu, Oct 19, 2023 at 7:47 PM Lorenzo Bianconi <
lorenzo.bianc...@redhat.com> wrote:

> Avoid recirculating IGMP/MLD packets more than one time from stage
> ls_out_pre_lb in the egress pipeline to ovn table 37 in order to avoid
> packet looping for ovn-ic deployment.
>
> Signed-off-by: Lorenzo Bianconi 
> ---
>  controller/pinctrl.c |  2 ++
>  include/ovn/logical-fields.h |  3 +++
>  lib/logical-fields.c |  4 
>  northd/northd.c  | 11 +++
>  4 files changed, 16 insertions(+), 4 deletions(-)
>
> diff --git a/controller/pinctrl.c b/controller/pinctrl.c
> index 3c1cecfde..d4ae7de46 100644
> --- a/controller/pinctrl.c
> +++ b/controller/pinctrl.c
> @@ -650,6 +650,8 @@ pinctrl_forward_pkt(struct rconn *swconn, int64_t
> dp_key,
>  put_load(dp_key, MFF_LOG_DATAPATH, 0, 64, );
>  put_load(in_port_key, MFF_LOG_INPORT, 0, 32, );
>  put_load(out_port_key, MFF_LOG_OUTPORT, 0, 32, );
> +/* Avoid re-injecting packet already consumed. */
> +put_load(1, MFF_LOG_FLAGS, MLF_IGMP_IGMP_SPOOF_INJECT_BIT, 1,
> );
>
>  struct ofpact_resubmit *resubmit = ofpact_put_RESUBMIT();
>  resubmit->in_port = OFPP_CONTROLLER;
> diff --git a/include/ovn/logical-fields.h b/include/ovn/logical-fields.h
> index a7b64ef67..0652af380 100644
> --- a/include/ovn/logical-fields.h
> +++ b/include/ovn/logical-fields.h
> @@ -77,6 +77,7 @@ enum mff_log_flags_bits {
>  MLF_CHECK_PORT_SEC_BIT = 12,
>  MLF_LOOKUP_COMMIT_ECMP_NH_BIT = 13,
>  MLF_USE_LB_AFF_SESSION_BIT = 14,
> +MLF_IGMP_IGMP_SPOOF_INJECT_BIT = 15,
>  };
>
>  /* MFF_LOG_FLAGS_REG flag assignments */
> @@ -124,6 +125,8 @@ enum mff_log_flags {
>  MLF_LOOKUP_COMMIT_ECMP_NH = (1 << MLF_LOOKUP_COMMIT_ECMP_NH_BIT),
>
>  MLF_USE_LB_AFF_SESSION = (1 << MLF_USE_LB_AFF_SESSION_BIT),
> +
> +MLF_IGMP_IGMP_SPOOF = (1 << MLF_IGMP_IGMP_SPOOF_INJECT_BIT),
>  };
>
>  /* OVN logical fields
> diff --git a/lib/logical-fields.c b/lib/logical-fields.c
> index fd509d9ee..3d8d5f950 100644
> --- a/lib/logical-fields.c
> +++ b/lib/logical-fields.c
> @@ -129,6 +129,10 @@ ovn_init_symtab(struct shash *symtab)
>   MLF_USE_SNAT_ZONE);
>  expr_symtab_add_subfield(symtab, "flags.use_snat_zone", NULL,
>   flags_str);
> +snprintf(flags_str, sizeof flags_str, "flags[%d]",
> + MLF_IGMP_IGMP_SPOOF_INJECT_BIT);
> +expr_symtab_add_subfield(symtab, "flags.igmp_loopback", NULL,
> + flags_str);
>
>  /* Connection tracking state. */
>  expr_symtab_add_field_scoped(symtab, "ct_mark", MFF_CT_MARK, NULL,
> false,
> diff --git a/northd/northd.c b/northd/northd.c
> index 916068d44..557fcca72 100644
> --- a/northd/northd.c
> +++ b/northd/northd.c
> @@ -7323,7 +7323,8 @@ build_interconn_mcast_snoop_flows(struct
> ovn_datapath *od,
>  continue;
>  }
>  /* Punt IGMP traffic to controller. */
> -char *match = xasprintf("inport == %s && igmp", op->json_key);
> +char *match = xasprintf("inport == %s && igmp && "
> +"flags.igmp_loopback == 0", op->json_key);
>  ovn_lflow_metered(lflows, od, S_SWITCH_OUT_PRE_LB, 120, match,
>"clone { igmp; }; next;",
>copp_meter_get(COPP_IGMP, od->nbs->copp,
> @@ -7331,7 +7332,8 @@ build_interconn_mcast_snoop_flows(struct
> ovn_datapath *od,
>  free(match);
>
>  /* Punt MLD traffic to controller. */
> -match = xasprintf("inport == %s && (mldv1 || mldv2)",
> op->json_key);
> +match = xasprintf("inport == %s && (mldv1 || mldv2) && "
> +  "flags.igmp_loopback == 0", op->json_key);
>  ovn_lflow_metered(lflows, od, S_SWITCH_OUT_PRE_LB, 120, match,
>"clone { igmp; }; next;",
>copp_meter_get(COPP_IGMP, od->nbs->copp,
> @@ -10317,13 +10319,14 @@ build_lswitch_destination_lookup_bmcast(struct
> ovn_datapath *od,
>  ds_put_cstr(actions, "igmp;");
>  /* Punt IGMP traffic to controller. */
>  ovn_lflow_metered(lflows, od, S_SWITCH_IN_L2_LKUP, 100,
> -  "igmp", ds_cstr(actions),
> +  "flags.igmp_loopback ==

[ovs-dev] [PATCH ovn v2 1/2] tests: Move ovn interconnection tests to ovn-ic.at.

2024-03-12 Thread Mohammad Heib
Move ovn-ic tests that exist in ovn.at to ovn-ic.at.

Signed-off-by: Mohammad Heib 
---
 tests/ovn-ic.at | 687 
 tests/ovn.at| 686 ---
 2 files changed, 687 insertions(+), 686 deletions(-)

diff --git a/tests/ovn-ic.at b/tests/ovn-ic.at
index 44dbf8ab1..12267e960 100644
--- a/tests/ovn-ic.at
+++ b/tests/ovn-ic.at
@@ -1442,3 +1442,690 @@ OVN_CLEANUP_IC([az1], [az2])
 
 AT_CLEANUP
 ])
+
+OVN_FOR_EACH_NORTHD([
+AT_SETUP([interconnection])
+AT_KEYWORDS([slowtest])
+
+ovn_init_ic_db
+# The number needs to stay relatively low due to high memory consumption
+# with address sanitizers enabled.
+n_az=3
+n_ts=3
+for i in `seq 1 $n_az`; do
+ovn_start az$i
+done
+
+net_add n1
+
+# 1 HV and 1 GW per AZ
+for az in `seq 1 $n_az`; do
+sim_add hv$az
+as hv$az
+check ovs-vsctl add-br br-phys
+ovn_az_attach az$az n1 br-phys 192.168.$az.1 16
+for p in `seq 1 $n_ts`; do
+check ovs-vsctl -- add-port br-int vif$p -- \
+set interface vif$p external-ids:iface-id=lsp$az-$p \
+options:tx_pcap=hv$az/vif$p-tx.pcap \
+options:rxq_pcap=hv$az/vif$p-rx.pcap \
+ofport-request=$p
+done
+
+sim_add gw$az
+as gw$az
+check ovs-vsctl add-br br-phys
+ovn_az_attach az$az n1 br-phys 192.168.$az.2 16
+check ovs-vsctl set open . external-ids:ovn-is-interconn=true
+done
+
+for ts in `seq 1 $n_ts`; do
+AT_CHECK([ovn-ic-nbctl create Transit_Switch name=ts$ts], [0], [ignore])
+for az in `seq 1 $n_az`; do
+echo "az$az: wait for ts$ts..."
+check ovn_as az$az ovn-nbctl wait-until logical_switch ts$ts
+done
+done
+
+for az in `seq 1 $n_az`; do
+ovn_as az$az
+check ovn-nbctl set nb_global . options:ic-route-learn=true
+check ovn-nbctl set nb_global . options:ic-route-adv=true
+
+# Each AZ has n_ts LSPi->LSi->LRi connecting to each TSi
+echo
+echo "az$az"
+for i in `seq 1 $n_ts`; do
+lsp_mac=00:00:00:0$az:0$i:00
+lrp_ls_mac=00:00:00:0$az:0$i:01
+lrp_ts_mac=00:00:00:0$az:0$i:02
+lsp_ip=10.$az.$i.123
+lrp_ls_ip=10.$az.$i.1
+lrp_ts_ip=169.254.$i.$az
+
+check ovn-nbctl ls-add ls$az-$i
+check ovn-nbctl lsp-add ls$az-$i lsp$az-$i
+check ovn-nbctl lsp-set-addresses lsp$az-$i "$lsp_mac $lsp_ip"
+
+check ovn-nbctl lr-add lr$az-$i
+
+check ovn-nbctl lrp-add lr$az-$i lrp-lr$az-$i-ls$az-$i $lrp_ls_mac 
$lrp_ls_ip/24
+check ovn-nbctl lsp-add ls$az-$i lsp-ls$az-$i-lr$az-$i
+check ovn-nbctl lsp-set-addresses lsp-ls$az-$i-lr$az-$i router
+check ovn-nbctl lsp-set-type lsp-ls$az-$i-lr$az-$i router
+check ovn-nbctl lsp-set-options lsp-ls$az-$i-lr$az-$i 
router-port=lrp-lr$az-$i-ls$az-$i
+
+check ovn-nbctl lrp-add lr$az-$i lrp-lr$az-$i-ts$i $lrp_ts_mac 
$lrp_ts_ip/24
+check ovn-nbctl lsp-add ts$i lsp-ts$i-lr$az-$i
+check ovn-nbctl lsp-set-addresses lsp-ts$i-lr$az-$i router
+check ovn-nbctl lsp-set-type lsp-ts$i-lr$az-$i router
+check ovn-nbctl lsp-set-options lsp-ts$i-lr$az-$i 
router-port=lrp-lr$az-$i-ts$i
+check ovn-nbctl lrp-set-gateway-chassis lrp-lr$az-$i-ts$i gw$az
+done
+check ovn-nbctl --wait=hv sync
+ovn-sbctl list Port_Binding > az$az.ports
+wait_for_ports_up
+done
+
+# Pre-populate the hypervisors' ARP tables so that we don't lose any
+# packets for ARP resolution (native tunneling doesn't queue packets
+# for ARP resolution).
+OVN_POPULATE_ARP
+
+for i in `seq 1 $n_az`; do
+check ovn_as az$i ovn-nbctl --wait=hv sync
+ovn_as az$i ovn-sbctl dump-flows > az$i/sbflows
+done
+
+# Allow some time for ovn-northd and ovn-controller to catch up.
+# XXX This should be more systematic.
+sleep 2
+
+# Populate requested-chassis options for remote lsps
+for az in $(seq 1 $n_az); do
+ovn_as az${az}
+for ts in $(seq 1 $n_ts); do
+for i in $(seq 1 $n_ts); do
+if [[ $i -eq ${az} ]]; then
+continue
+fi
+check ovn-nbctl lsp-set-options lsp-ts${ts}-lr${i}-${ts} 
requested-chassis=gw$i
+done
+done
+done
+
+ovn-ic-nbctl show > ic-nbctl.dump
+AT_CAPTURE_FILE([ic-nbctl.dump])
+
+(echo "-ISB dump-"
+ ovn-ic-sbctl show
+ echo "-"
+ ovn-ic-sbctl list gateway
+ echo "-"
+ ovn-ic-sbctl list datapath_binding
+ echo "-"
+ ovn-ic-sbctl list port_binding
+ echo "-"
+ ovn-ic-sbctl list route
+ echo "-") > ic-sbctl.dump
+AT_CAPTURE_FILE([ic-sbctl.dump])
+
+AT_CAPTURE_FILE([expected])
+AT_CAPTURE_FILE([received])
+check_packets() {
+> expected
+> received
+for az in `seq 1 $n_az`; do
+for i in `seq 1 $n_ts`; do
+pcap=hv$az

[ovs-dev] [PATCH ovn v2 2/2] tests: Use sync command in ovn-ic tests.

2024-03-12 Thread Mohammad Heib
Use the sync commands in the ovn-ic unit tests
and remove lines that wait for IC-SB to sync with IC-NB.

Signed-off-by: Mohammad Heib 
---
 tests/ovn-ic.at | 178 
 1 file changed, 72 insertions(+), 106 deletions(-)

diff --git a/tests/ovn-ic.at b/tests/ovn-ic.at
index 12267e960..4a24e171b 100644
--- a/tests/ovn-ic.at
+++ b/tests/ovn-ic.at
@@ -6,7 +6,7 @@ ovn_init_ic_db
 ovn_start az1
 ovn_start az2
 
-wait_row_count ic-sb:Availability_Zone 2
+check ovn-ic-nbctl --wait=sb sync
 AT_CHECK([ovn-ic-sbctl show], [0], [dnl
 availability-zone az1
 availability-zone az2
@@ -31,7 +31,6 @@ OVN_CLEANUP_IC([az1], [az2])
 AT_CLEANUP
 ])
 
-
 OVN_FOR_EACH_NORTHD([
 AT_SETUP([ovn-ic -- AZ update in GW])
 ovn_init_ic_db
@@ -47,10 +46,12 @@ check ovs-vsctl set open . 
external-ids:ovn-is-interconn=true
 
 az_uuid=$(fetch_column ic-sb:availability-zone _uuid name="az1")
 ovn_as az1 ovn-nbctl set NB_Global . name="az2"
-wait_column "$az_uuid" ic-sb:availability-zone _uuid name="az2"
+
+check ovn-ic-nbctl --wait=sb sync
+check_column "$az_uuid" ic-sb:availability-zone _uuid name="az2"
 
 # make sure that gateway still point to the same AZ with new name
-wait_column "$az_uuid" ic-sb:gateway availability_zone name="gw-az1"
+check_column "$az_uuid" ic-sb:gateway availability_zone name="gw-az1"
 
 OVN_CLEANUP_IC([az1])
 AT_CLEANUP
@@ -66,11 +67,11 @@ ovn_start az1
 ovn-sbctl chassis-add fakechassis vxlan 192.168.0.2
 
 AT_CHECK([ovn-ic-nbctl ts-add ts1])
-AT_CHECK([ovn-ic-nbctl ts-add ts2])
+AT_CHECK([ovn-ic-nbctl --wait=sb ts-add ts2])
 
 # Check ISB
-wait_row_count ic-sb:Datapath_Binding 1 transit_switch=ts1
-wait_row_count ic-sb:Datapath_Binding 1 transit_switch=ts2
+check_row_count ic-sb:Datapath_Binding 1 transit_switch=ts1
+check_row_count ic-sb:Datapath_Binding 1 transit_switch=ts2
 check_column "ts1 ts2" ic-sb:Datapath_Binding transit_switch
 check_column "ts1 ts2" nb:Logical_Switch name
 
@@ -81,8 +82,8 @@ ts1_key=$(fetch_column ic-sb:Datapath_Binding tunnel_key 
transit_switch=ts1)
 check_column "$ts1_key" Datapath_Binding tunnel_key 
external_ids:interconn-ts=ts1
 
 # Test delete
-AT_CHECK([ovn-ic-nbctl ts-del ts1])
-wait_row_count ic-sb:Datapath_Binding 0 transit_switch=ts1
+AT_CHECK([ovn-ic-nbctl --wait=sb ts-del ts1])
+check_row_count ic-sb:Datapath_Binding 0 transit_switch=ts1
 check_column ts2 ic-sb:Datapath_Binding transit_switch
 check_column ts2 nb:Logical_Switch name
 
@@ -111,12 +112,11 @@ done
 ovn_as az1
 
 # create transit switch and connect to LR
-check ovn-ic-nbctl ts-add ts1
+check ovn-ic-nbctl --wait=sb ts-add ts1
 check ovn-nbctl lr-add lr1
 check ovn-nbctl lrp-add lr1 lrp1 00:00:00:00:00:01 10.0.0.1/24
 check ovn-nbctl lrp-set-gateway-chassis lrp1 gw-az1
 
-OVS_WAIT_UNTIL([ovn-nbctl show | grep switch | grep ts1])
 check ovn-nbctl lsp-add ts1 lsp1 -- \
 lsp-set-addresses lsp1 router -- \
 lsp-set-type lsp1 router -- \
@@ -124,8 +124,8 @@ check ovn-nbctl lsp-add ts1 lsp1 -- \
 
 wait_row_count Datapath_Binding 1 external_ids:interconn-ts=ts1
 
-# check port binding appeared
-OVS_WAIT_UNTIL([ovn-ic-sbctl show | grep lsp1])
+# Sync ic-sb DB to see the TS changes.
+check ovn-ic-nbctl --wait=sb sync
 
 AT_CHECK([ovn-ic-sbctl show | grep -A2 lsp1], [0], [dnl
 port lsp1
@@ -134,8 +134,8 @@ AT_CHECK([ovn-ic-sbctl show | grep -A2 lsp1], [0], [dnl
 ])
 
 # remove transit switch and check if port_binding is deleted
-check ovn-ic-nbctl ts-del ts1
-wait_row_count ic-sb:Port_Binding 0 logical_port=lsp1
+check ovn-ic-nbctl --wait=sb ts-del ts1
+check_row_count ic-sb:Port_Binding 0 logical_port=lsp1
 for i in 1 2; do
 az=az$i
 ovn_as $az
@@ -180,8 +180,7 @@ create_ic_infra() {
 
 ovn_as $az
 
-check ovn-ic-nbctl ts-add $ts
-OVS_WAIT_UNTIL([ovn-nbctl show | grep switch | grep $ts])
+check ovn-ic-nbctl --wait=sb ts-add $ts
 check ovn-nbctl lr-add $lr
 check ovn-nbctl lrp-add $lr $lrp 00:00:00:00:00:0$az_id 10.0.$az_id.1/24
 check ovn-nbctl lrp-set-gateway-chassis $lrp gw-$az
@@ -197,18 +196,18 @@ create_ic_infra() {
 create_ic_infra 1 1
 create_ic_infra 1 2
 create_ic_infra 2 1
+check ovn-ic-nbctl --wait=sb sync
 
 ovn_as az1
 
-wait_row_count ic-sb:Route 3 ip_prefix=192.168.0.0/16
+check_row_count ic-sb:Route 3 ip_prefix=192.168.0.0/16
 
 # remove transit switch 1 (from az1) and check if its route is deleted
 # same route from another AZ and ts should remain, as
-check ovn-ic-nbctl ts-del ts1-1
-sleep 2
+check ovn-ic-nbctl --wait=sb ts-del ts1-1
 ovn-ic-sbctl list route
 ovn-ic-nbctl list transit_switch
-wait_row_count ic-sb:route 2 ip_prefix=192.168.0.0/16
+checl_row_count ic-sb:route 2 ip_prefix=192.168.0.0/16
 ovn-ic-sbctl list route
 
 for i in 1 2; do
@@ -246,7 +245,7 @@ done
 ovn_as az1
 
 # create transit switch and connect to LR
-check ovn-ic-nbctl ts-add ts1
+check ovn-ic-nbctl --w

[ovs-dev] [PATCH ovn v3] controller: Release container lport when releasing parent port.

2024-02-28 Thread Mohammad Heib
Currently if the user sets the container parent_port:requested-chassis
option after the VIF/CIF is bonded to the chassis, this will migrate
the VIF/CIF flows to the new chassis but will still have the
container flows installed in the old chassis which can allow unwanted
tagged traffic to reach VMS/containers on the old chassis.

This patch will resolve the above issue by remove the CIF flows
from the old chassis and prevent the CIF from being bonded to a
chassis different from the parent port VIF binding chassis.

Rreported-at: https://bugzilla.redhat.com/show_bug.cgi?id=2220938
Signed-off-by: Mohammad Heib 
---
 controller/binding.c  |  3 +++
 controller/physical.c |  9 
 tests/ovn.at  | 53 +++
 3 files changed, 65 insertions(+)

diff --git a/controller/binding.c b/controller/binding.c
index 2afc5d48a..c2d15a6c4 100644
--- a/controller/binding.c
+++ b/controller/binding.c
@@ -1710,6 +1710,9 @@ consider_container_lport(const struct sbrec_port_binding 
*pb,
 
 ovs_assert(parent_b_lport && parent_b_lport->pb);
 bool can_bind = lport_can_bind_on_this_chassis(b_ctx_in->chassis_rec, pb);
+/* cannot bind to this chassis if the parent_port cannot be bounded. */
+can_bind &= lport_can_bind_on_this_chassis(b_ctx_in->chassis_rec,
+   parent_b_lport->pb);
 
 return consider_vif_lport_(pb, can_bind, b_ctx_in, b_ctx_out,
container_b_lport);
diff --git a/controller/physical.c b/controller/physical.c
index 7ef259da4..86d4b4578 100644
--- a/controller/physical.c
+++ b/controller/physical.c
@@ -1631,6 +1631,15 @@ consider_port_binding(struct ovsdb_idl_index 
*sbrec_port_binding_by_name,
 nested_container = true;
 parent_port = lport_lookup_by_name(
 sbrec_port_binding_by_name, binding->parent_port);
+
+if (parent_port
+&& !lport_can_bind_on_this_chassis(chassis, parent_port)) {
+/* Even though there is an ofport for this container
+ * parent port, it is requested on different chassis ignore
+ * this container port.
+ */
+return;
+}
 }
 } else if (!strcmp(binding->type, "localnet")
  || !strcmp(binding->type, "l2gateway")) {
diff --git a/tests/ovn.at b/tests/ovn.at
index d26c95054..6f0fc1043 100644
--- a/tests/ovn.at
+++ b/tests/ovn.at
@@ -38351,3 +38351,56 @@ OVS_WAIT_UNTIL([test 1 = $(as hv ovs-ofctl dump-flows 
br-int | grep -E "pkt_mark
 OVN_CLEANUP([hv])
 AT_CLEANUP
 ])
+
+OVN_FOR_EACH_NORTHD([
+AT_SETUP([ovn-controller - cleanup VIF/CIF related flows/fields when updating 
requested-chassis])
+ovn_start
+
+net_add n1
+sim_add hv1
+ovs-vsctl add-br br-phys
+ovn_attach n1 br-phys 192.168.0.1
+check ovs-vsctl -- add-port br-int vif1 -- \
+set Interface vif1 external-ids:iface-id=lsp1 \
+ofport-request=8
+
+check ovn-nbctl ls-add lsw0
+
+check ovn-nbctl lsp-add lsw0 lsp1
+check ovn-nbctl lsp-add lsw0 sw0-port1.1 lsp1 7
+
+# wait for the VIF to be claimed to this chassis
+wait_row_count Chassis 1 name=hv1
+hv1_uuid=$(fetch_column Chassis _uuid name=hv1)
+wait_for_ports_up lsp1
+wait_for_ports_up sw0-port1.1
+wait_column "$hv1_uuid" Port_Binding chassis logical_port=lsp1
+wait_column "$hv1_uuid" Port_Binding chassis logical_port=sw0-port1.1
+
+# check that flows is installed
+OVS_WAIT_FOR_OUTPUT([as hv1 ovs-ofctl dump-flows br-int table=0 |grep 
priority=100 | grep -c in_port=8], [0],[dnl
+1
+])
+OVS_WAIT_FOR_OUTPUT([as hv1 ovs-ofctl dump-flows br-int table=0 |grep 
priority=150|grep dl_vlan=7| grep -c in_port=8], [0],[dnl
+1
+])
+
+# set lport requested-chassis to differant chassis
+check ovn-nbctl set Logical_Switch_Port lsp1 \
+options:requested-chassis=foo
+
+OVS_WAIT_UNTIL([test `ovn-sbctl get Port_Binding lsp1 up` = 'false'])
+OVS_WAIT_UNTIL([test `ovn-sbctl get Port_Binding sw0-port1.1 up` = 'false'])
+wait_column "" Port_Binding chassis logical_port=lsp1
+wait_column "" Port_Binding chassis logical_port=sw0-port1.1
+
+OVS_WAIT_FOR_OUTPUT([as hv1 ovs-ofctl dump-flows br-int table=0 |grep 
priority=100 |grep -c in_port=8], [1],[dnl
+0
+])
+OVS_WAIT_FOR_OUTPUT([as hv1 ovs-ofctl dump-flows br-int table=0 |grep 
priority=150|grep dl_vlan=7| grep -c in_port=8], [1],[dnl
+0
+])
+
+OVN_CLEANUP([hv1])
+AT_CLEANUP
+])
-- 
2.34.3

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


Re: [ovs-dev] [PATCH ovn v2] ci: Update crun in GitHub actions runner.

2024-02-27 Thread Mohammad Heib
Hi Dumitru,
Thank you for your review :)
i was confused because the fix
<https://noobient.com/2023/11/15/fixing-ubuntu-containers-failing-to-start-with-systemd/>
mentioned Docker as well,
but you are right the default is runc so we don't have to update the ovn-k
workflow.
addressed in v3
thanks
On Wed, Feb 28, 2024 at 12:00 AM Dumitru Ceara  wrote:

> On 2/27/24 17:28, Mohammad Heib wrote:
> > There are some issues with older crun and newer kernel
> > combination [0]. Unfortunately Ubuntu 22.04 falls into this
> > category and the jobs will often time fail. Temoprarily use
> > newer crun from git that has the fix [1].
> >
> > [0] https://github.com/containers/crun/pull/1309
> > [1]
> https://noobient.com/2023/11/15/fixing-ubuntu-containers-failing-to-start-with-systemd/
> >
> > Signed-off-by: Mohammad Heib 
> > ---
>
> Hi Mohammad,
>
> Thanks for working on fixing the CI!
>
> >  .github/workflows/ovn-fake-multinode-tests.yml | 8 
> >  .github/workflows/ovn-kubernetes.yml   | 8 
> >  .github/workflows/test.yml | 8 
> >  3 files changed, 24 insertions(+)
> >
> > diff --git a/.github/workflows/ovn-fake-multinode-tests.yml
> b/.github/workflows/ovn-fake-multinode-tests.yml
> > index 179c1d662..79b6c4253 100644
> > --- a/.github/workflows/ovn-fake-multinode-tests.yml
> > +++ b/.github/workflows/ovn-fake-multinode-tests.yml
> > @@ -137,6 +137,14 @@ jobs:
> >  sudo systemctl start openvswitch-switch
> >  sudo ovs-vsctl show
> >
> > +# XXX This should be removed when native crun >=1.9.1
> > +- name: update crun script
> > +  run: |
> > +crun --version
> > +sudo curl -L "
> https://github.com/containers/crun/releases/download/1.14.1/crun-1.14.1-linux-amd64;
> -o /usr/bin/crun
> > +sudo chmod +x /usr/bin/crun
> > +echo "New crun version: "$(crun --version)
> > +
> >  - name: Start basic cluster
> >run: |
> >  sudo -E ./ovn_cluster.sh start
> > diff --git a/.github/workflows/ovn-kubernetes.yml
> b/.github/workflows/ovn-kubernetes.yml
> > index 0f2b30497..09a838cfe 100644
> > --- a/.github/workflows/ovn-kubernetes.yml
> > +++ b/.github/workflows/ovn-kubernetes.yml
> > @@ -140,6 +140,14 @@ jobs:
> >run: |
> >  docker load --input image.tar && rm -rf image.tar
> >
> > +# XXX This should be removed when native crun >=1.9.1
> > +- name: update crun script
> > +  run: |
> > +crun --version
> > +sudo curl -L "
> https://github.com/containers/crun/releases/download/1.14.1/crun-1.14.1-linux-amd64;
> -o /usr/bin/crun
> > +sudo chmod +x /usr/bin/crun
> > +echo "New crun version: "$(crun --version)
> > +
>
> We don't install podman anywhere for ovn-kubernetes jobs (maybe we
> should but that's a different story) so kind will use docker.  I don't
> think we need to update (install?) crun.  AFAICT docker/containerd uses
> runc as runtime so we shouldn't be having any issues for ovn-k jobs.
>
> What do you think?
>
> >  - name: kind setup
> >run: |
> >  export OVN_IMAGE="ovn-daemonset-f:dev"
> > diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml
> > index 2def39531..0cb981775 100644
> > --- a/.github/workflows/test.yml
> > +++ b/.github/workflows/test.yml
> > @@ -217,6 +217,14 @@ jobs:
> >  path: /tmp/image.tar
> >  key: ${{ github.sha }}
> >
> > +# XXX This should be removed when native crun >=1.9.1
> > +- name: update crun script
> > +  run: |
> > +crun --version
> > +sudo curl -L "
> https://github.com/containers/crun/releases/download/1.14.1/crun-1.14.1-linux-amd64;
> -o /usr/bin/crun
> > +sudo chmod +x /usr/bin/crun
> > +echo "New crun version: "$(crun --version)
> > +
> >  - name: load image
> >run: |
> >  sudo podman load -i /tmp/image.tar
>
> The rest looks good to me, thanks!
>
> Regards,
> Dumitru
>
>
___
dev mailing list
d...@openvswitch.org
https://mail.openvswitch.org/mailman/listinfo/ovs-dev


[ovs-dev] [PATCH ovn v3] ci: Update crun in GitHub actions runner.

2024-02-27 Thread Mohammad Heib
There are some issues with older crun and newer kernel
combination [0]. Unfortunately Ubuntu 22.04 falls into this
category and the jobs will often time fail. Temoprarily use
newer crun from git that has the fix [1].

[0] https://github.com/containers/crun/pull/1309
[1] 
https://noobient.com/2023/11/15/fixing-ubuntu-containers-failing-to-start-with-systemd/

Signed-off-by: Mohammad Heib 
---
 .github/workflows/ovn-fake-multinode-tests.yml | 8 
 .github/workflows/test.yml | 8 
 2 files changed, 16 insertions(+)

diff --git a/.github/workflows/ovn-fake-multinode-tests.yml 
b/.github/workflows/ovn-fake-multinode-tests.yml
index 179c1d662..79b6c4253 100644
--- a/.github/workflows/ovn-fake-multinode-tests.yml
+++ b/.github/workflows/ovn-fake-multinode-tests.yml
@@ -137,6 +137,14 @@ jobs:
 sudo systemctl start openvswitch-switch
 sudo ovs-vsctl show
 
+# XXX This should be removed when native crun >=1.9.1
+- name: update crun script
+  run: |
+crun --version
+sudo curl -L 
"https://github.com/containers/crun/releases/download/1.14.1/crun-1.14.1-linux-amd64;
 -o /usr/bin/crun
+sudo chmod +x /usr/bin/crun
+echo "New crun version: "$(crun --version)
+
 - name: Start basic cluster
   run: |
 sudo -E ./ovn_cluster.sh start
diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml
index 2def39531..0cb981775 100644
--- a/.github/workflows/test.yml
+++ b/.github/workflows/test.yml
@@ -217,6 +217,14 @@ jobs:
 path: /tmp/image.tar
 key: ${{ github.sha }}
 
+# XXX This should be removed when native crun >=1.9.1
+- name: update crun script
+  run: |
+crun --version
+sudo curl -L 
"https://github.com/containers/crun/releases/download/1.14.1/crun-1.14.1-linux-amd64;
 -o /usr/bin/crun
+sudo chmod +x /usr/bin/crun
+echo "New crun version: "$(crun --version)
+
 - name: load image
   run: |
 sudo podman load -i /tmp/image.tar
-- 
2.34.3

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


[ovs-dev] [PATCH ovn] ci: Update crun in GitHub actions runer.

2024-02-27 Thread Mohammad Heib
There are some issues with older crun and newer kernel
combination [0]. Unfortunately Ubuntu 22.04 falls into this
category and the jobs will often time fail. Temoprarily use
newer crun from git that has the fix [1].

[0] https://github.com/containers/crun/pull/1309
[1] 
https://noobient.com/2023/11/15/fixing-ubuntu-containers-failing-to-start-with-systemd/

Signed-off-by: Mohammad Heib 
---
 .github/workflows/ovn-fake-multinode-tests.yml | 8 
 .github/workflows/ovn-kubernetes.yml   | 8 
 .github/workflows/test.yml | 8 
 3 files changed, 24 insertions(+)

diff --git a/.github/workflows/ovn-fake-multinode-tests.yml 
b/.github/workflows/ovn-fake-multinode-tests.yml
index 179c1d662..79b6c4253 100644
--- a/.github/workflows/ovn-fake-multinode-tests.yml
+++ b/.github/workflows/ovn-fake-multinode-tests.yml
@@ -137,6 +137,14 @@ jobs:
 sudo systemctl start openvswitch-switch
 sudo ovs-vsctl show
 
+# XXX This should be removed when native crun >=1.9.1
+- name: update crun script
+  run: |
+crun --version
+sudo curl -L 
"https://github.com/containers/crun/releases/download/1.14.1/crun-1.14.1-linux-amd64;
 -o /usr/bin/crun
+sudo chmod +x /usr/bin/crun
+echo "New crun version: "$(crun --version)
+
 - name: Start basic cluster
   run: |
 sudo -E ./ovn_cluster.sh start
diff --git a/.github/workflows/ovn-kubernetes.yml 
b/.github/workflows/ovn-kubernetes.yml
index 0f2b30497..09a838cfe 100644
--- a/.github/workflows/ovn-kubernetes.yml
+++ b/.github/workflows/ovn-kubernetes.yml
@@ -140,6 +140,14 @@ jobs:
   run: |
 docker load --input image.tar && rm -rf image.tar
 
+# XXX This should be removed when native crun >=1.9.1
+- name: update crun script
+  run: |
+crun --version
+sudo curl -L 
"https://github.com/containers/crun/releases/download/1.14.1/crun-1.14.1-linux-amd64;
 -o /usr/bin/crun
+sudo chmod +x /usr/bin/crun
+echo "New crun version: "$(crun --version)
+
 - name: kind setup
   run: |
 export OVN_IMAGE="ovn-daemonset-f:dev"
diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml
index 2def39531..0cb981775 100644
--- a/.github/workflows/test.yml
+++ b/.github/workflows/test.yml
@@ -217,6 +217,14 @@ jobs:
 path: /tmp/image.tar
 key: ${{ github.sha }}
 
+# XXX This should be removed when native crun >=1.9.1
+- name: update crun script
+  run: |
+crun --version
+sudo curl -L 
"https://github.com/containers/crun/releases/download/1.14.1/crun-1.14.1-linux-amd64;
 -o /usr/bin/crun
+sudo chmod +x /usr/bin/crun
+echo "New crun version: "$(crun --version)
+
 - name: load image
   run: |
 sudo podman load -i /tmp/image.tar
-- 
2.34.3

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


[ovs-dev] [PATCH ovn v2] ci: Update crun in GitHub actions runner.

2024-02-27 Thread Mohammad Heib
There are some issues with older crun and newer kernel
combination [0]. Unfortunately Ubuntu 22.04 falls into this
category and the jobs will often time fail. Temoprarily use
newer crun from git that has the fix [1].

[0] https://github.com/containers/crun/pull/1309
[1] 
https://noobient.com/2023/11/15/fixing-ubuntu-containers-failing-to-start-with-systemd/

Signed-off-by: Mohammad Heib 
---
 .github/workflows/ovn-fake-multinode-tests.yml | 8 
 .github/workflows/ovn-kubernetes.yml   | 8 
 .github/workflows/test.yml | 8 
 3 files changed, 24 insertions(+)

diff --git a/.github/workflows/ovn-fake-multinode-tests.yml 
b/.github/workflows/ovn-fake-multinode-tests.yml
index 179c1d662..79b6c4253 100644
--- a/.github/workflows/ovn-fake-multinode-tests.yml
+++ b/.github/workflows/ovn-fake-multinode-tests.yml
@@ -137,6 +137,14 @@ jobs:
 sudo systemctl start openvswitch-switch
 sudo ovs-vsctl show
 
+# XXX This should be removed when native crun >=1.9.1
+- name: update crun script
+  run: |
+crun --version
+sudo curl -L 
"https://github.com/containers/crun/releases/download/1.14.1/crun-1.14.1-linux-amd64;
 -o /usr/bin/crun
+sudo chmod +x /usr/bin/crun
+echo "New crun version: "$(crun --version)
+
 - name: Start basic cluster
   run: |
 sudo -E ./ovn_cluster.sh start
diff --git a/.github/workflows/ovn-kubernetes.yml 
b/.github/workflows/ovn-kubernetes.yml
index 0f2b30497..09a838cfe 100644
--- a/.github/workflows/ovn-kubernetes.yml
+++ b/.github/workflows/ovn-kubernetes.yml
@@ -140,6 +140,14 @@ jobs:
   run: |
 docker load --input image.tar && rm -rf image.tar
 
+# XXX This should be removed when native crun >=1.9.1
+- name: update crun script
+  run: |
+crun --version
+sudo curl -L 
"https://github.com/containers/crun/releases/download/1.14.1/crun-1.14.1-linux-amd64;
 -o /usr/bin/crun
+sudo chmod +x /usr/bin/crun
+echo "New crun version: "$(crun --version)
+
 - name: kind setup
   run: |
 export OVN_IMAGE="ovn-daemonset-f:dev"
diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml
index 2def39531..0cb981775 100644
--- a/.github/workflows/test.yml
+++ b/.github/workflows/test.yml
@@ -217,6 +217,14 @@ jobs:
 path: /tmp/image.tar
 key: ${{ github.sha }}
 
+# XXX This should be removed when native crun >=1.9.1
+- name: update crun script
+  run: |
+crun --version
+sudo curl -L 
"https://github.com/containers/crun/releases/download/1.14.1/crun-1.14.1-linux-amd64;
 -o /usr/bin/crun
+sudo chmod +x /usr/bin/crun
+echo "New crun version: "$(crun --version)
+
 - name: load image
   run: |
 sudo podman load -i /tmp/image.tar
-- 
2.34.3

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


[ovs-dev] [PATCH ovn] ci: Update crun in GitHub actions runer.

2024-02-27 Thread Mohammad Heib
There are some issues with older crun and newer kernel
combination [0]. Unfortunately Ubuntu 22.04 falls into this
category and the jobs will often time fail. Temoprarily use
newer crun from git that has the fix [1].

[0] https://github.com/containers/crun/pull/1309
[1] 
https://noobient.com/2023/11/15/fixing-ubuntu-containers-failing-to-start-with-systemd/

Signed-off-by: Mohammad Heib 
---
 .github/workflows/ovn-fake-multinode-tests.yml | 8 
 .github/workflows/ovn-kubernetes.yml   | 8 
 .github/workflows/test.yml | 8 
 3 files changed, 24 insertions(+)

diff --git a/.github/workflows/ovn-fake-multinode-tests.yml 
b/.github/workflows/ovn-fake-multinode-tests.yml
index 179c1d662..79b6c4253 100644
--- a/.github/workflows/ovn-fake-multinode-tests.yml
+++ b/.github/workflows/ovn-fake-multinode-tests.yml
@@ -137,6 +137,14 @@ jobs:
 sudo systemctl start openvswitch-switch
 sudo ovs-vsctl show
 
+# XXX This should be removed when native crun >=1.9.1
+- name: update crun script
+  run: |
+crun --version
+sudo curl -L 
"https://github.com/containers/crun/releases/download/1.14.1/crun-1.14.1-linux-amd64;
 -o /usr/bin/crun
+sudo chmod +x /usr/bin/crun
+echo "New crun version: "$(crun --version)
+
 - name: Start basic cluster
   run: |
 sudo -E ./ovn_cluster.sh start
diff --git a/.github/workflows/ovn-kubernetes.yml 
b/.github/workflows/ovn-kubernetes.yml
index 0f2b30497..09a838cfe 100644
--- a/.github/workflows/ovn-kubernetes.yml
+++ b/.github/workflows/ovn-kubernetes.yml
@@ -140,6 +140,14 @@ jobs:
   run: |
 docker load --input image.tar && rm -rf image.tar
 
+# XXX This should be removed when native crun >=1.9.1
+- name: update crun script
+  run: |
+crun --version
+sudo curl -L 
"https://github.com/containers/crun/releases/download/1.14.1/crun-1.14.1-linux-amd64;
 -o /usr/bin/crun
+sudo chmod +x /usr/bin/crun
+echo "New crun version: "$(crun --version)
+
 - name: kind setup
   run: |
 export OVN_IMAGE="ovn-daemonset-f:dev"
diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml
index 2def39531..0cb981775 100644
--- a/.github/workflows/test.yml
+++ b/.github/workflows/test.yml
@@ -217,6 +217,14 @@ jobs:
 path: /tmp/image.tar
 key: ${{ github.sha }}
 
+# XXX This should be removed when native crun >=1.9.1
+- name: update crun script
+  run: |
+crun --version
+sudo curl -L 
"https://github.com/containers/crun/releases/download/1.14.1/crun-1.14.1-linux-amd64;
 -o /usr/bin/crun
+sudo chmod +x /usr/bin/crun
+echo "New crun version: "$(crun --version)
+
 - name: load image
   run: |
 sudo podman load -i /tmp/image.tar
-- 
2.34.3

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


[ovs-dev] [PATCH ovn 1/2] tests: Move ovn interconnection tests to ovn-ic.at.

2024-02-27 Thread Mohammad Heib
Move ovn-ic tests that exist in ovn.at to ovn-ic.at.

Signed-off-by: Mohammad Heib 
---
 tests/ovn-ic.at | 687 
 tests/ovn.at| 686 ---
 2 files changed, 687 insertions(+), 686 deletions(-)

diff --git a/tests/ovn-ic.at b/tests/ovn-ic.at
index 44dbf8ab1..12267e960 100644
--- a/tests/ovn-ic.at
+++ b/tests/ovn-ic.at
@@ -1442,3 +1442,690 @@ OVN_CLEANUP_IC([az1], [az2])
 
 AT_CLEANUP
 ])
+
+OVN_FOR_EACH_NORTHD([
+AT_SETUP([interconnection])
+AT_KEYWORDS([slowtest])
+
+ovn_init_ic_db
+# The number needs to stay relatively low due to high memory consumption
+# with address sanitizers enabled.
+n_az=3
+n_ts=3
+for i in `seq 1 $n_az`; do
+ovn_start az$i
+done
+
+net_add n1
+
+# 1 HV and 1 GW per AZ
+for az in `seq 1 $n_az`; do
+sim_add hv$az
+as hv$az
+check ovs-vsctl add-br br-phys
+ovn_az_attach az$az n1 br-phys 192.168.$az.1 16
+for p in `seq 1 $n_ts`; do
+check ovs-vsctl -- add-port br-int vif$p -- \
+set interface vif$p external-ids:iface-id=lsp$az-$p \
+options:tx_pcap=hv$az/vif$p-tx.pcap \
+options:rxq_pcap=hv$az/vif$p-rx.pcap \
+ofport-request=$p
+done
+
+sim_add gw$az
+as gw$az
+check ovs-vsctl add-br br-phys
+ovn_az_attach az$az n1 br-phys 192.168.$az.2 16
+check ovs-vsctl set open . external-ids:ovn-is-interconn=true
+done
+
+for ts in `seq 1 $n_ts`; do
+AT_CHECK([ovn-ic-nbctl create Transit_Switch name=ts$ts], [0], [ignore])
+for az in `seq 1 $n_az`; do
+echo "az$az: wait for ts$ts..."
+check ovn_as az$az ovn-nbctl wait-until logical_switch ts$ts
+done
+done
+
+for az in `seq 1 $n_az`; do
+ovn_as az$az
+check ovn-nbctl set nb_global . options:ic-route-learn=true
+check ovn-nbctl set nb_global . options:ic-route-adv=true
+
+# Each AZ has n_ts LSPi->LSi->LRi connecting to each TSi
+echo
+echo "az$az"
+for i in `seq 1 $n_ts`; do
+lsp_mac=00:00:00:0$az:0$i:00
+lrp_ls_mac=00:00:00:0$az:0$i:01
+lrp_ts_mac=00:00:00:0$az:0$i:02
+lsp_ip=10.$az.$i.123
+lrp_ls_ip=10.$az.$i.1
+lrp_ts_ip=169.254.$i.$az
+
+check ovn-nbctl ls-add ls$az-$i
+check ovn-nbctl lsp-add ls$az-$i lsp$az-$i
+check ovn-nbctl lsp-set-addresses lsp$az-$i "$lsp_mac $lsp_ip"
+
+check ovn-nbctl lr-add lr$az-$i
+
+check ovn-nbctl lrp-add lr$az-$i lrp-lr$az-$i-ls$az-$i $lrp_ls_mac 
$lrp_ls_ip/24
+check ovn-nbctl lsp-add ls$az-$i lsp-ls$az-$i-lr$az-$i
+check ovn-nbctl lsp-set-addresses lsp-ls$az-$i-lr$az-$i router
+check ovn-nbctl lsp-set-type lsp-ls$az-$i-lr$az-$i router
+check ovn-nbctl lsp-set-options lsp-ls$az-$i-lr$az-$i 
router-port=lrp-lr$az-$i-ls$az-$i
+
+check ovn-nbctl lrp-add lr$az-$i lrp-lr$az-$i-ts$i $lrp_ts_mac 
$lrp_ts_ip/24
+check ovn-nbctl lsp-add ts$i lsp-ts$i-lr$az-$i
+check ovn-nbctl lsp-set-addresses lsp-ts$i-lr$az-$i router
+check ovn-nbctl lsp-set-type lsp-ts$i-lr$az-$i router
+check ovn-nbctl lsp-set-options lsp-ts$i-lr$az-$i 
router-port=lrp-lr$az-$i-ts$i
+check ovn-nbctl lrp-set-gateway-chassis lrp-lr$az-$i-ts$i gw$az
+done
+check ovn-nbctl --wait=hv sync
+ovn-sbctl list Port_Binding > az$az.ports
+wait_for_ports_up
+done
+
+# Pre-populate the hypervisors' ARP tables so that we don't lose any
+# packets for ARP resolution (native tunneling doesn't queue packets
+# for ARP resolution).
+OVN_POPULATE_ARP
+
+for i in `seq 1 $n_az`; do
+check ovn_as az$i ovn-nbctl --wait=hv sync
+ovn_as az$i ovn-sbctl dump-flows > az$i/sbflows
+done
+
+# Allow some time for ovn-northd and ovn-controller to catch up.
+# XXX This should be more systematic.
+sleep 2
+
+# Populate requested-chassis options for remote lsps
+for az in $(seq 1 $n_az); do
+ovn_as az${az}
+for ts in $(seq 1 $n_ts); do
+for i in $(seq 1 $n_ts); do
+if [[ $i -eq ${az} ]]; then
+continue
+fi
+check ovn-nbctl lsp-set-options lsp-ts${ts}-lr${i}-${ts} 
requested-chassis=gw$i
+done
+done
+done
+
+ovn-ic-nbctl show > ic-nbctl.dump
+AT_CAPTURE_FILE([ic-nbctl.dump])
+
+(echo "-ISB dump-"
+ ovn-ic-sbctl show
+ echo "-"
+ ovn-ic-sbctl list gateway
+ echo "-"
+ ovn-ic-sbctl list datapath_binding
+ echo "-"
+ ovn-ic-sbctl list port_binding
+ echo "-"
+ ovn-ic-sbctl list route
+ echo "-") > ic-sbctl.dump
+AT_CAPTURE_FILE([ic-sbctl.dump])
+
+AT_CAPTURE_FILE([expected])
+AT_CAPTURE_FILE([received])
+check_packets() {
+> expected
+> received
+for az in `seq 1 $n_az`; do
+for i in `seq 1 $n_ts`; do
+pcap=hv$az

[ovs-dev] [PATCH ovn 2/2] tests: Use sync command in ovn-ic tests.

2024-02-27 Thread Mohammad Heib
Use the sync commands in the ovn-ic unit tests
and remove lines that wait for IC-SB to sync with IC-NB.

Signed-off-by: Mohammad Heib 
---
 tests/ovn-ic.at | 178 
 1 file changed, 72 insertions(+), 106 deletions(-)

diff --git a/tests/ovn-ic.at b/tests/ovn-ic.at
index 12267e960..4a24e171b 100644
--- a/tests/ovn-ic.at
+++ b/tests/ovn-ic.at
@@ -6,7 +6,7 @@ ovn_init_ic_db
 ovn_start az1
 ovn_start az2
 
-wait_row_count ic-sb:Availability_Zone 2
+check ovn-ic-nbctl --wait=sb sync
 AT_CHECK([ovn-ic-sbctl show], [0], [dnl
 availability-zone az1
 availability-zone az2
@@ -31,7 +31,6 @@ OVN_CLEANUP_IC([az1], [az2])
 AT_CLEANUP
 ])
 
-
 OVN_FOR_EACH_NORTHD([
 AT_SETUP([ovn-ic -- AZ update in GW])
 ovn_init_ic_db
@@ -47,10 +46,12 @@ check ovs-vsctl set open . 
external-ids:ovn-is-interconn=true
 
 az_uuid=$(fetch_column ic-sb:availability-zone _uuid name="az1")
 ovn_as az1 ovn-nbctl set NB_Global . name="az2"
-wait_column "$az_uuid" ic-sb:availability-zone _uuid name="az2"
+
+check ovn-ic-nbctl --wait=sb sync
+check_column "$az_uuid" ic-sb:availability-zone _uuid name="az2"
 
 # make sure that gateway still point to the same AZ with new name
-wait_column "$az_uuid" ic-sb:gateway availability_zone name="gw-az1"
+check_column "$az_uuid" ic-sb:gateway availability_zone name="gw-az1"
 
 OVN_CLEANUP_IC([az1])
 AT_CLEANUP
@@ -66,11 +67,11 @@ ovn_start az1
 ovn-sbctl chassis-add fakechassis vxlan 192.168.0.2
 
 AT_CHECK([ovn-ic-nbctl ts-add ts1])
-AT_CHECK([ovn-ic-nbctl ts-add ts2])
+AT_CHECK([ovn-ic-nbctl --wait=sb ts-add ts2])
 
 # Check ISB
-wait_row_count ic-sb:Datapath_Binding 1 transit_switch=ts1
-wait_row_count ic-sb:Datapath_Binding 1 transit_switch=ts2
+check_row_count ic-sb:Datapath_Binding 1 transit_switch=ts1
+check_row_count ic-sb:Datapath_Binding 1 transit_switch=ts2
 check_column "ts1 ts2" ic-sb:Datapath_Binding transit_switch
 check_column "ts1 ts2" nb:Logical_Switch name
 
@@ -81,8 +82,8 @@ ts1_key=$(fetch_column ic-sb:Datapath_Binding tunnel_key 
transit_switch=ts1)
 check_column "$ts1_key" Datapath_Binding tunnel_key 
external_ids:interconn-ts=ts1
 
 # Test delete
-AT_CHECK([ovn-ic-nbctl ts-del ts1])
-wait_row_count ic-sb:Datapath_Binding 0 transit_switch=ts1
+AT_CHECK([ovn-ic-nbctl --wait=sb ts-del ts1])
+check_row_count ic-sb:Datapath_Binding 0 transit_switch=ts1
 check_column ts2 ic-sb:Datapath_Binding transit_switch
 check_column ts2 nb:Logical_Switch name
 
@@ -111,12 +112,11 @@ done
 ovn_as az1
 
 # create transit switch and connect to LR
-check ovn-ic-nbctl ts-add ts1
+check ovn-ic-nbctl --wait=sb ts-add ts1
 check ovn-nbctl lr-add lr1
 check ovn-nbctl lrp-add lr1 lrp1 00:00:00:00:00:01 10.0.0.1/24
 check ovn-nbctl lrp-set-gateway-chassis lrp1 gw-az1
 
-OVS_WAIT_UNTIL([ovn-nbctl show | grep switch | grep ts1])
 check ovn-nbctl lsp-add ts1 lsp1 -- \
 lsp-set-addresses lsp1 router -- \
 lsp-set-type lsp1 router -- \
@@ -124,8 +124,8 @@ check ovn-nbctl lsp-add ts1 lsp1 -- \
 
 wait_row_count Datapath_Binding 1 external_ids:interconn-ts=ts1
 
-# check port binding appeared
-OVS_WAIT_UNTIL([ovn-ic-sbctl show | grep lsp1])
+# Sync ic-sb DB to see the TS changes.
+check ovn-ic-nbctl --wait=sb sync
 
 AT_CHECK([ovn-ic-sbctl show | grep -A2 lsp1], [0], [dnl
 port lsp1
@@ -134,8 +134,8 @@ AT_CHECK([ovn-ic-sbctl show | grep -A2 lsp1], [0], [dnl
 ])
 
 # remove transit switch and check if port_binding is deleted
-check ovn-ic-nbctl ts-del ts1
-wait_row_count ic-sb:Port_Binding 0 logical_port=lsp1
+check ovn-ic-nbctl --wait=sb ts-del ts1
+check_row_count ic-sb:Port_Binding 0 logical_port=lsp1
 for i in 1 2; do
 az=az$i
 ovn_as $az
@@ -180,8 +180,7 @@ create_ic_infra() {
 
 ovn_as $az
 
-check ovn-ic-nbctl ts-add $ts
-OVS_WAIT_UNTIL([ovn-nbctl show | grep switch | grep $ts])
+check ovn-ic-nbctl --wait=sb ts-add $ts
 check ovn-nbctl lr-add $lr
 check ovn-nbctl lrp-add $lr $lrp 00:00:00:00:00:0$az_id 10.0.$az_id.1/24
 check ovn-nbctl lrp-set-gateway-chassis $lrp gw-$az
@@ -197,18 +196,18 @@ create_ic_infra() {
 create_ic_infra 1 1
 create_ic_infra 1 2
 create_ic_infra 2 1
+check ovn-ic-nbctl --wait=sb sync
 
 ovn_as az1
 
-wait_row_count ic-sb:Route 3 ip_prefix=192.168.0.0/16
+check_row_count ic-sb:Route 3 ip_prefix=192.168.0.0/16
 
 # remove transit switch 1 (from az1) and check if its route is deleted
 # same route from another AZ and ts should remain, as
-check ovn-ic-nbctl ts-del ts1-1
-sleep 2
+check ovn-ic-nbctl --wait=sb ts-del ts1-1
 ovn-ic-sbctl list route
 ovn-ic-nbctl list transit_switch
-wait_row_count ic-sb:route 2 ip_prefix=192.168.0.0/16
+checl_row_count ic-sb:route 2 ip_prefix=192.168.0.0/16
 ovn-ic-sbctl list route
 
 for i in 1 2; do
@@ -246,7 +245,7 @@ done
 ovn_as az1
 
 # create transit switch and connect to LR
-check ovn-ic-nbctl ts-add ts1
+check ovn-ic-nbctl --w

Re: [ovs-dev] [PATCH ovn] ovn-controller: Stop dropping bind_vport requests immediately after handling.

2024-02-26 Thread Mohammad Heib
Hi Ales,
Thank you for the review
i addressed all your comments in v2.
regarding the test actually, it's a bit hard to test that using a unit test
because we need to let ovn-sb ignore the first binding request which is not
applicable using a unit test, i was testing that manually by dropping the
connection to the SB that will drop the first bind request but it a bit
hard
to do that i an unit test.


On Fri, Feb 2, 2024 at 1:21 PM Ales Musil  wrote:

>
>
> On Fri, Feb 2, 2024 at 12:19 PM Ales Musil  wrote:
>
>>
>>
>> On Tue, Jan 30, 2024 at 2:59 PM Mohammad Heib  wrote:
>>
>>> ovn-controller immediately removes the vport_bindings requests that were
>>> generated by VIFs after handling them locally, this approach is intended
>>> to avoid binding the vport to one VIF only and allocate the vport
>>> between the different VIFs that exist in the vport:virtual-parents.
>>>
>>> Although the behavior mentioned above is correct, in some cases when the
>>> SB Database is busy the transaction that binds this vport to the desired
>>> VIF/chassis can fail and the controller will not re-try to bind the
>>> vport again because we deleted the bind_vport request in the previous
>>> loop/TXN.
>>>
>>> This patch aims to change the above behavior by storing the bind_vport
>>> requests for a bit longer time and this is done by the following:
>>> 1. add relevancy_time for each new bind_vport request and
>>>mark this request as new.
>>>
>>> 2. loop0: ovn-controller will try to handle this bind_vport request
>>>for the first time as usual (no change).
>>>
>>>3. loop0: ovn-controller will try to delete the already handled
>>> bind_vport
>>>   request as usual but first, it will check if this request is
>>> marked as new and
>>>   if the relevancy_time is still valid if so the controller will
>>> mark this
>>>   request as an old request and keep it, otherwise remove it.
>>>
>>>4.loop1: ovn-controller will try to commit the same change again for
>>>  the old request, if the previous commit in loop0 succeeded the
>>>  change will not have any effect on SB, otherwise we will try to
>>>  commit the same vport_bind request again.
>>>
>>>   5. loop1: delete the old bind_vport request.
>>>
>>> Reported-at: https://bugzilla.redhat.com/show_bug.cgi?id=1954659
>>> Signed-off-by: Mohammad Heib 
>>> ---
>>>
>>
>> Hi  Mohammad,
>>
>> overall the change makes sense, I have a couple of comments see down
>> below.
>>
>>  controller/pinctrl.c | 58 +++-
>>>  1 file changed, 52 insertions(+), 6 deletions(-)
>>>
>>> diff --git a/controller/pinctrl.c b/controller/pinctrl.c
>>> index bd3bd3d81..152962448 100644
>>> --- a/controller/pinctrl.c
>>> +++ b/controller/pinctrl.c
>>> @@ -6519,10 +6519,52 @@ struct put_vport_binding {
>>>  uint32_t vport_key;
>>>
>>>  uint32_t vport_parent_key;
>>> +
>>> +/* This vport record Only relevant if "relevancy_time"
>>> + * is earlier than the current_time, "new_record" is true.
>>> + */
>>> +long long int relevancy_time;
>>>
>>
>> The intention of the variable should be probably clearer e.g.
>> relevant_until_ms.
>>
>> Also reading through the rest of the code it doesn't seem possible that
>> the binding wouldn't be deleted, hence I think there isn't any need for the
>> relevancy time, it should be enough to have a flag that will be flipped. In
>> any case we will try to commit twice. I would leave out the whole relevancy
>> and keep the flag flipping it on first commit WDYT?
>>
>>
>>> +bool new_record;
>>>  };
>>>
>>>  /* Contains "struct put_vport_binding"s. */
>>>  static struct hmap put_vport_bindings;
>>> +/* the relevance time in ms of vport record before deleteing. */
>>> +#define VPORT_RELEVANCE_TIME 1500
>>> +
>>> +/*
>>> + * Validate if the vport_binding record that was added
>>> + * by the pinctrl thread is still relevant and needs
>>> + * to be updated in the SBDB or not.
>>> + *
>>> + * vport_binding record is only relevant and needs to be updated in SB
>>> if:
>>> + *   1. The put_vport_binding:relevancy_time still valid.
>>> + *   2. The put_vport_binding:new_rec

[ovs-dev] [PATCH ovn v2] ovn-controller: Stop dropping bind_vport requests immediately after handling.

2024-02-26 Thread Mohammad Heib
ovn-controller immediately removes the vport_bindings requests that were
generated by VIFs after handling them locally, this approach is intended
to avoid binding the vport to one VIF only and allocate the vport
between the different VIFs that exist in the vport:virtual-parents.

Although the behavior mentioned above is correct, in some cases when the
SB Database is busy the transaction that binds this vport to the desired
VIF/chassis can fail and the controller will not re-try to bind the
vport again because we deleted the bind_vport request in the previous
loop/TXN.

This patch aims to change the above behavior by storing the bind_vport
requests for a bit longer time and this is done by the following:
1. mark each new bind_vport request as new.

2. loop0: ovn-controller will try to handle this bind_vport request
   for the first time as usual (no change).

3. loop0: ovn-controller will try to delete the already handled bind_vport
   request as usual but first, it will check if this request is marked as 
new and
   if so the controller will mark this request as an old request and keep 
it,
   otherwise remove it.

4. loop1: ovn-controller will try to commit the same change again for
   the old request, if the previous commit in loop0 succeeded the
   change will not have any effect on SB, otherwise we will try to
   commit the same vport_bind request again.

5. loop1: delete the old bind_vport request.

Reported-at: https://bugzilla.redhat.com/show_bug.cgi?id=1954659
Signed-off-by: Mohammad Heib 
---
V2:
  Address comments from Ales in v1.
---
 controller/pinctrl.c | 50 ++--
 1 file changed, 44 insertions(+), 6 deletions(-)

diff --git a/controller/pinctrl.c b/controller/pinctrl.c
index 98b29de9f..e2f86f299 100644
--- a/controller/pinctrl.c
+++ b/controller/pinctrl.c
@@ -6529,11 +6529,46 @@ struct put_vport_binding {
 uint32_t vport_key;
 
 uint32_t vport_parent_key;
+
+/* This vport record Only relevant if "new_record" is true. */
+bool new_record;
 };
 
 /* Contains "struct put_vport_binding"s. */
 static struct hmap put_vport_bindings;
 
+/*
+ * Validate if the vport_binding record that was added
+ * by the pinctrl thread is still relevant and needs
+ * to be updated in the SBDB or not.
+ *
+ * vport_binding record is only relevant and needs to be updated in SB if:
+ *   2. The put_vport_binding:new_record is true:
+ *   The new_record will be set to "true" when this vport record is created
+ *   by function "pinctrl_handle_bind_vport".
+ *
+ *   After the first attempt to bind this vport to the chassis and
+ *   virtual_parent by function "run_put_vport_bindings" we will set the
+ *   value of vpb:new_record to "false" and keep it in "put_vport_bindings"
+ *
+ *   After the second attempt of binding the vpb it will be removed by
+ *   this function.
+ *
+ *   The above guarantees that we will try to bind the vport twice in
+ *   a certain amount of time.
+ *
+*/
+static bool
+is_vport_binding_relevant(struct put_vport_binding *vpb)
+{
+
+if (vpb->new_record) {
+vpb->new_record = false;
+return true;
+}
+return false;
+}
+
 static void
 init_put_vport_bindings(void)
 {
@@ -6541,18 +6576,21 @@ init_put_vport_bindings(void)
 }
 
 static void
-flush_put_vport_bindings(void)
+flush_put_vport_bindings(bool force_flush)
 {
 struct put_vport_binding *vport_b;
-HMAP_FOR_EACH_POP (vport_b, hmap_node, _vport_bindings) {
-free(vport_b);
+HMAP_FOR_EACH_SAFE (vport_b, hmap_node, _vport_bindings) {
+if (!is_vport_binding_relevant(vport_b) || force_flush) {
+hmap_remove(_vport_bindings, _b->hmap_node);
+free(vport_b);
+}
 }
 }
 
 static void
 destroy_put_vport_bindings(void)
 {
-flush_put_vport_bindings();
+flush_put_vport_bindings(true);
 hmap_destroy(_vport_bindings);
 }
 
@@ -6630,7 +6668,7 @@ run_put_vport_bindings(struct ovsdb_idl_txn 
*ovnsb_idl_txn,
   sbrec_port_binding_by_key, chassis, vpb);
 }
 
-flush_put_vport_bindings();
+flush_put_vport_bindings(false);
 }
 
 /* Called with in the pinctrl_handler thread context. */
@@ -6668,7 +6706,7 @@ pinctrl_handle_bind_vport(
 vpb->dp_key = dp_key;
 vpb->vport_key = vport_key;
 vpb->vport_parent_key = vport_parent_key;
-
+vpb->new_record = true;
 notify_pinctrl_main();
 }
 
-- 
2.34.3

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


[ovs-dev] [PATCH ovn v3] OVN-SB: Exposes igmp group protocol version through IGMP table.

2024-02-26 Thread Mohammad Heib
Expose the igmp/mld group protocol version through the
IGMP_GROUP table in SBDB.

This patch can be used by ovn consumer for debuggability purposes, user
now can  match between the protocol version used in the OVN logical
switches and the uplink ports.

Rreported-at: https://bugzilla.redhat.com/show_bug.cgi?id=2160476
Signed-off-by: Mohammad Heib 
---
v3:
  Address Ales comments in v2 and rebase over main.
---
 NEWS  |  2 ++
 controller/ip-mcast.c | 11 +--
 controller/ip-mcast.h | 11 ++-
 controller/pinctrl.c  | 16 ++--
 northd/ovn-northd.c   |  2 +-
 ovn-sb.ovsschema  |  5 +++--
 ovn-sb.xml|  4 
 tests/ovn.at  |  3 +++
 8 files changed, 42 insertions(+), 12 deletions(-)

diff --git a/NEWS b/NEWS
index c0131ceee..784fedfa0 100644
--- a/NEWS
+++ b/NEWS
@@ -5,6 +5,8 @@ Post v24.03.0
 cloned to all unknown ports connected to the same Logical Switch.
   - Added a new logical switch port option "disable_arp_nd_rsp" to
 disable adding the ARP responder flows if set to true.
+  - IGMP_Group has new "protocol" column that displays the the group
+protocol version.
 
 OVN v24.03.0 - xx xxx 
 --
diff --git a/controller/ip-mcast.c b/controller/ip-mcast.c
index b457c7e69..0969cc07f 100644
--- a/controller/ip-mcast.c
+++ b/controller/ip-mcast.c
@@ -111,11 +111,12 @@ igmp_mrouter_create(struct ovsdb_idl_txn *idl_txn,
 }
 
 void
-igmp_group_update_ports(const struct sbrec_igmp_group *g,
+igmp_group_update(const struct sbrec_igmp_group *g,
 struct ovsdb_idl_index *datapaths,
 struct ovsdb_idl_index *port_bindings,
 const struct mcast_snooping *ms OVS_UNUSED,
-const struct mcast_group *mc_group)
+const struct mcast_group *mc_group,
+const bool igmp_support_protocol)
 OVS_REQ_RDLOCK(ms->rwlock)
 {
 struct igmp_group_port *old_ports_storage =
@@ -155,6 +156,12 @@ igmp_group_update_ports(const struct sbrec_igmp_group *g,
 sbrec_igmp_group_update_ports_delvalue(g, igmp_port->port);
 }
 
+/* set Group protocol */
+if (igmp_support_protocol) {
+ sbrec_igmp_group_set_protocol(g, mcast_snooping_group_protocol_str(
+   mc_group->protocol_version));
+}
+
 free(old_ports_storage);
 hmap_destroy(_ports);
 }
diff --git a/controller/ip-mcast.h b/controller/ip-mcast.h
index eebada968..026503139 100644
--- a/controller/ip-mcast.h
+++ b/controller/ip-mcast.h
@@ -47,11 +47,12 @@ struct sbrec_igmp_group *igmp_mrouter_create(
 const struct sbrec_chassis *chassis,
 bool igmp_group_has_chassis_name);
 
-void igmp_group_update_ports(const struct sbrec_igmp_group *g,
- struct ovsdb_idl_index *datapaths,
- struct ovsdb_idl_index *port_bindings,
- const struct mcast_snooping *ms,
- const struct mcast_group *mc_group)
+void igmp_group_update(const struct sbrec_igmp_group *g,
+   struct ovsdb_idl_index *datapaths,
+   struct ovsdb_idl_index *port_bindings,
+   const struct mcast_snooping *ms,
+   const struct mcast_group *mc_group,
+   const bool igmp_support_protocol)
 OVS_REQ_RDLOCK(ms->rwlock);
 void
 igmp_mrouter_update_ports(const struct sbrec_igmp_group *g,
diff --git a/controller/pinctrl.c b/controller/pinctrl.c
index 98b29de9f..66e390e80 100644
--- a/controller/pinctrl.c
+++ b/controller/pinctrl.c
@@ -181,6 +181,7 @@ struct pinctrl {
 bool fdb_can_timestamp;
 bool dns_supports_ovn_owned;
 bool igmp_group_has_chassis_name;
+bool igmp_support_protocol;
 };
 
 static struct pinctrl pinctrl;
@@ -3599,6 +3600,17 @@ pinctrl_update(const struct ovsdb_idl *idl, const char 
*br_int_name)
 notify_pinctrl_handler();
 }
 
+bool igmp_support_proto =
+sbrec_server_has_igmp_group_table_col_protocol(idl);
+if (igmp_support_proto != pinctrl.igmp_support_protocol) {
+pinctrl.igmp_support_protocol = igmp_support_proto;
+
+/* Notify pinctrl_handler that igmp protocol column
+ * availability has changed. */
+notify_pinctrl_handler();
+}
+
+
 ovs_mutex_unlock(_mutex);
 }
 
@@ -5409,9 +5421,9 @@ ip_mcast_sync(struct ovsdb_idl_txn *ovnsb_idl_txn,
 chassis, pinctrl.igmp_group_has_chassis_name);
 }
 
-igmp_group_update_ports(sbrec_igmp, sbrec_datapath_binding_by_key,
+igmp_group_update(sbrec_igmp, sbrec_datapath_binding_by_key,
 sbrec_port_binding_by_key, ip_ms->ms,
-mc_group);
+mc_group, pinctrl.igmp_support_protocol);
 }
 

[ovs-dev] [PATCH ovn v2] OVN-SB: Exposes igmp group protocol version through IGMP table.

2024-01-31 Thread Mohammad Heib
Expose the igmp/mld group protocol version through the
IGMP_GROUP table in SBDB.

This patch can be used by ovn consumer for debuggability purposes, user
now can  match between the protocol version used in the OVN logical
switches and the uplink ports.

Rreported-at: https://bugzilla.redhat.com/show_bug.cgi?id=2160476
Signed-off-by: Mohammad Heib 
---
 NEWS  |  2 ++
 controller/ip-mcast.c | 10 --
 controller/ip-mcast.h |  5 +++--
 controller/pinctrl.c  | 28 
 northd/ovn-northd.c   |  2 +-
 ovn-sb.ovsschema  |  5 +++--
 ovn-sb.xml|  4 
 tests/ovn.at  |  3 +++
 8 files changed, 48 insertions(+), 11 deletions(-)

diff --git a/NEWS b/NEWS
index 6553bd078..6505ef22b 100644
--- a/NEWS
+++ b/NEWS
@@ -18,6 +18,8 @@ Post v23.09.0
   - Support selecting encapsulation IP based on the source/destination VIF's
 settting. See ovn-controller(8) 'external_ids:ovn-encap-ip' for more
 details.
+  - IGMP_Group has new "protocol" column that displays the the group
+protocol version.
 
 OVN v23.09.0 - 15 Sep 2023
 --
diff --git a/controller/ip-mcast.c b/controller/ip-mcast.c
index a870fb29e..18a3e1fc2 100644
--- a/controller/ip-mcast.c
+++ b/controller/ip-mcast.c
@@ -107,11 +107,12 @@ igmp_mrouter_create(struct ovsdb_idl_txn *idl_txn,
 }
 
 void
-igmp_group_update_ports(const struct sbrec_igmp_group *g,
+igmp_group_update(const struct sbrec_igmp_group *g,
 struct ovsdb_idl_index *datapaths,
 struct ovsdb_idl_index *port_bindings,
 const struct mcast_snooping *ms OVS_UNUSED,
-const struct mcast_group *mc_group)
+const struct mcast_group *mc_group,
+const char *protocol)
 OVS_REQ_RDLOCK(ms->rwlock)
 {
 struct igmp_group_port *old_ports_storage =
@@ -151,6 +152,11 @@ igmp_group_update_ports(const struct sbrec_igmp_group *g,
 sbrec_igmp_group_update_ports_delvalue(g, igmp_port->port);
 }
 
+/* set Group protocol */
+if (protocol) {
+ sbrec_igmp_group_set_protocol(g, protocol);
+}
+
 free(old_ports_storage);
 hmap_destroy(_ports);
 }
diff --git a/controller/ip-mcast.h b/controller/ip-mcast.h
index 326f39db1..2a8921976 100644
--- a/controller/ip-mcast.h
+++ b/controller/ip-mcast.h
@@ -45,11 +45,12 @@ struct sbrec_igmp_group *igmp_mrouter_create(
 const struct sbrec_datapath_binding *datapath,
 const struct sbrec_chassis *chassis);
 
-void igmp_group_update_ports(const struct sbrec_igmp_group *g,
+void igmp_group_update(const struct sbrec_igmp_group *g,
  struct ovsdb_idl_index *datapaths,
  struct ovsdb_idl_index *port_bindings,
  const struct mcast_snooping *ms,
- const struct mcast_group *mc_group)
+ const struct mcast_group *mc_group,
+ const char *protocol)
 OVS_REQ_RDLOCK(ms->rwlock);
 void
 igmp_mrouter_update_ports(const struct sbrec_igmp_group *g,
diff --git a/controller/pinctrl.c b/controller/pinctrl.c
index bd3bd3d81..f3597b489 100644
--- a/controller/pinctrl.c
+++ b/controller/pinctrl.c
@@ -180,6 +180,7 @@ struct pinctrl {
 bool mac_binding_can_timestamp;
 bool fdb_can_timestamp;
 bool dns_supports_ovn_owned;
+bool igmp_support_protocol;
 };
 
 static struct pinctrl pinctrl;
@@ -3586,11 +3587,21 @@ pinctrl_update(const struct ovsdb_idl *idl, const char 
*br_int_name)
 if (dns_supports_ovn_owned != pinctrl.dns_supports_ovn_owned) {
 pinctrl.dns_supports_ovn_owned = dns_supports_ovn_owned;
 
-/* Notify pinctrl_handler that fdb timestamp column
+/* Notify pinctrl_handler that dns ovn_owned column
* availability has changed. */
 notify_pinctrl_handler();
 }
 
+bool igmp_support_proto =
+sbrec_server_has_igmp_group_table_col_protocol(idl);
+if (igmp_support_proto != pinctrl.igmp_support_protocol) {
+pinctrl.igmp_support_protocol = igmp_support_proto;
+
+/* Notify pinctrl_handler that igmp protocol column
+ * availability has changed. */
+notify_pinctrl_handler();
+}
+
 ovs_mutex_unlock(_mutex);
 }
 
@@ -5400,9 +5411,18 @@ ip_mcast_sync(struct ovsdb_idl_txn *ovnsb_idl_txn,
local_dp->datapath, chassis);
 }
 
-igmp_group_update_ports(sbrec_igmp, sbrec_datapath_binding_by_key,
-sbrec_port_binding_by_key, ip_ms->ms,
-mc_group);
+/* Set Group protocol if supported */
+if (pinctrl.igmp_support_protocol) {
+igmp_group_update(sbrec_igmp, sbrec_datapath_binding_by_key,
+  sbrec_port_

[ovs-dev] [PATCH ovn] ovn-controller: Stop dropping bind_vport requests immediately after handling.

2024-01-30 Thread Mohammad Heib
ovn-controller immediately removes the vport_bindings requests that were
generated by VIFs after handling them locally, this approach is intended
to avoid binding the vport to one VIF only and allocate the vport
between the different VIFs that exist in the vport:virtual-parents.

Although the behavior mentioned above is correct, in some cases when the
SB Database is busy the transaction that binds this vport to the desired
VIF/chassis can fail and the controller will not re-try to bind the
vport again because we deleted the bind_vport request in the previous
loop/TXN.

This patch aims to change the above behavior by storing the bind_vport
requests for a bit longer time and this is done by the following:
1. add relevancy_time for each new bind_vport request and
   mark this request as new.

2. loop0: ovn-controller will try to handle this bind_vport request
   for the first time as usual (no change).

   3. loop0: ovn-controller will try to delete the already handled bind_vport
  request as usual but first, it will check if this request is marked as 
new and
  if the relevancy_time is still valid if so the controller will mark this
  request as an old request and keep it, otherwise remove it.

   4.loop1: ovn-controller will try to commit the same change again for
 the old request, if the previous commit in loop0 succeeded the
 change will not have any effect on SB, otherwise we will try to
 commit the same vport_bind request again.

  5. loop1: delete the old bind_vport request.

Reported-at: https://bugzilla.redhat.com/show_bug.cgi?id=1954659
Signed-off-by: Mohammad Heib 
---
 controller/pinctrl.c | 58 +++-
 1 file changed, 52 insertions(+), 6 deletions(-)

diff --git a/controller/pinctrl.c b/controller/pinctrl.c
index bd3bd3d81..152962448 100644
--- a/controller/pinctrl.c
+++ b/controller/pinctrl.c
@@ -6519,10 +6519,52 @@ struct put_vport_binding {
 uint32_t vport_key;
 
 uint32_t vport_parent_key;
+
+/* This vport record Only relevant if "relevancy_time"
+ * is earlier than the current_time, "new_record" is true.
+ */
+long long int relevancy_time;
+bool new_record;
 };
 
 /* Contains "struct put_vport_binding"s. */
 static struct hmap put_vport_bindings;
+/* the relevance time in ms of vport record before deleteing. */
+#define VPORT_RELEVANCE_TIME 1500
+
+/*
+ * Validate if the vport_binding record that was added
+ * by the pinctrl thread is still relevant and needs
+ * to be updated in the SBDB or not.
+ *
+ * vport_binding record is only relevant and needs to be updated in SB if:
+ *   1. The put_vport_binding:relevancy_time still valid.
+ *   2. The put_vport_binding:new_record is true:
+ *   The new_record will be set to "true" when this vport record is created
+ *   by function "pinctrl_handle_bind_vport".
+ *
+ *   After the first attempt to bind this vport to the chassis and
+ *   virtual_parent by function "run_put_vport_bindings" we will set the
+ *   value of vpb:new_record to "false" and keep it in "put_vport_bindings"
+ *
+ *   After the second attempt of binding the vpb it will be removed by
+ *   this function.
+ *
+ *   The above guarantees that we will try to bind the vport twice in
+ *   a certain amount of time.
+ *
+*/
+static bool
+is_vport_binding_relevant(struct put_vport_binding *vpb)
+{
+long long int cur_time = time_msec();
+
+if (vpb->new_record && vpb->relevancy_time > cur_time) {
+vpb->new_record = false;
+return true;
+}
+return false;
+}
 
 static void
 init_put_vport_bindings(void)
@@ -6531,18 +6573,21 @@ init_put_vport_bindings(void)
 }
 
 static void
-flush_put_vport_bindings(void)
+flush_put_vport_bindings(bool force_flush)
 {
 struct put_vport_binding *vport_b;
-HMAP_FOR_EACH_POP (vport_b, hmap_node, _vport_bindings) {
-free(vport_b);
+HMAP_FOR_EACH_SAFE (vport_b, hmap_node, _vport_bindings) {
+if (!is_vport_binding_relevant(vport_b) || force_flush) {
+hmap_remove(_vport_bindings, _b->hmap_node);
+free(vport_b);
+}
 }
 }
 
 static void
 destroy_put_vport_bindings(void)
 {
-flush_put_vport_bindings();
+flush_put_vport_bindings(true);
 hmap_destroy(_vport_bindings);
 }
 
@@ -6620,7 +6665,7 @@ run_put_vport_bindings(struct ovsdb_idl_txn 
*ovnsb_idl_txn,
   sbrec_port_binding_by_key, chassis, vpb);
 }
 
-flush_put_vport_bindings();
+flush_put_vport_bindings(false);
 }
 
 /* Called with in the pinctrl_handler thread context. */
@@ -6658,7 +6703,8 @@ pinctrl_handle_bind_vport(
 vpb->dp_key = dp_key;
 vpb->vport_key = vport_key;
 vpb->vport_parent_key = vport_parent_key;
-
+vpb->new_record = true;
+vpb->relevancy_time = time_msec() + VPORT_RELEVANCE

Re: [ovs-dev] [PATCH ovn] ovs: Bump submodule to latest OVS branch-3.3.

2024-01-30 Thread Mohammad Heib
Hi,
Thank you Dumitru.

Acked-by: Mohammad Heib 

On Tue, Jan 30, 2024 at 11:16 AM Eelco Chaudron  wrote:

>
>
> On 30 Jan 2024, at 9:57, Dumitru Ceara wrote:
>
> > On 1/30/24 09:04, Eelco Chaudron wrote:
> >>
> >>
> >> On 30 Jan 2024, at 0:36, Dumitru Ceara wrote:
> >>
> >>> This picks up the following relevant OVS commits:
> >>>   8893e24d9d dpdk: Update to use v23.11.
> >>>   ed738eca39 util: Annotate function that will never return NULL.
> >>>   77d0bad04 mcast-snooping: Store IGMP/MLD protocol version.
> >>>   b222593bc6 mcast-snooping: Add group protocol to mdb/show output.
> >>>   a940a691e7 ovs-atomic: Fix inclusion of Clang header by GCC 14.
> >>>   b0cf73112d dp-packet: Reset offload/offsets when clearing a packet.
> >>>
> >>> This commit also ports the CI DPDK related changes from OVS commit
> >>> 8893e24d9d09 ("dpdk: Update to use v23.11.") which are required as
> 23.11
> >>> is the supported DPDK branch on OVS 3.3.  There's also a small change
> >>> that had to be made when mangling the prefix path of the installed
> >>> DPDK version in the container.
> >>>
> >>> As a side effect this will also address OVN Fedora 40 (rawhide) build
> >>> failures on aarch64 and s390x.  They are fixed by a940a691e7d9
> >>> ("ovs-atomic: Fix inclusion of Clang header by GCC 14.").
> >>>
> >>> Suggested-by: Ilya Maximets 
> >>> Signed-off-by: Dumitru Ceara 
> >>
> >> There is also a change in controller/pinctrl.c, any reason why this is
> part of this patch?
> >>
> >
> > Yes, b222593bc6 ("mcast-snooping: Add group protocol to mdb/show
> > output") changed the OVS mcast library API.  That's used by OVN.  We
> > need that pinctrl.c change otherwise compilation fails.
>
> Thanks Dumitru for the clarification, maybe you can add this to the commit
> message when you apply? The rest looks good, and as the tests passed;
>
> Acked-by: Eelco Chaudron 
>
>
>
___
dev mailing list
d...@openvswitch.org
https://mail.openvswitch.org/mailman/listinfo/ovs-dev


Re: [ovs-dev] [PATCH] mcast-snooping: Remove typedef from mcast_group_proto.

2024-01-28 Thread Mohammad Heib
Thanks, Ilya,
Looks good to me.

Acked-by: Mohammad Heib 

Thanks,



On Fri, Jan 26, 2024 at 7:11 PM Ilya Maximets  wrote:

> Typedefs are confusing and the coding style generally advises to not
> use them.  Removing typedef until others start using it.
>
> This typedef already got me while testing an OVN update to use OVS 3.3
> as a submodule, since the variable was declared in a switch statement
> and it wasn't clearly visible that there is a variable definition in
> one of the cases and braces should be used.  Strangely some versions
> of compilers do not require braces in this case, so OVN change works
> locally, but not in CI.
>
> Fixes: 077d0bad0436 ("mcast-snooping: Store IGMP/MLD protocol version.")
> Signed-off-by: Ilya Maximets 
> ---
>  lib/mcast-snooping.c |  6 +++---
>  lib/mcast-snooping.h | 12 ++--
>  ofproto/ofproto-dpif-xlate.c |  2 +-
>  3 files changed, 10 insertions(+), 10 deletions(-)
>
> diff --git a/lib/mcast-snooping.c b/lib/mcast-snooping.c
> index 60ef8381e..dc5164b41 100644
> --- a/lib/mcast-snooping.c
> +++ b/lib/mcast-snooping.c
> @@ -58,7 +58,7 @@ mcast_snooping_flood_unreg(const struct mcast_snooping
> *ms)
>  }
>
>  char *
> -mcast_snooping_group_protocol_str(mcast_group_proto grp_proto)
> +mcast_snooping_group_protocol_str(enum mcast_group_proto grp_proto)
>  {
>  switch (grp_proto) {
>  case MCAST_GROUP_IGMPV1:
> @@ -414,7 +414,7 @@ bool
>  mcast_snooping_add_group(struct mcast_snooping *ms,
>   const struct in6_addr *addr,
>   uint16_t vlan, void *port,
> - mcast_group_proto grp_proto)
> + enum mcast_group_proto grp_proto)
>  OVS_REQ_WRLOCK(ms->rwlock)
>  {
>  bool learned;
> @@ -460,7 +460,7 @@ mcast_snooping_add_group(struct mcast_snooping *ms,
>  bool
>  mcast_snooping_add_group4(struct mcast_snooping *ms, ovs_be32 ip4,
>   uint16_t vlan, void *port,
> - mcast_group_proto grp_proto)
> + enum mcast_group_proto grp_proto)
>  OVS_REQ_WRLOCK(ms->rwlock)
>  {
>  struct in6_addr addr = in6_addr_mapped_ipv4(ip4);
> diff --git a/lib/mcast-snooping.h b/lib/mcast-snooping.h
> index 76ab4e4f7..de42cf826 100644
> --- a/lib/mcast-snooping.h
> +++ b/lib/mcast-snooping.h
> @@ -40,13 +40,13 @@ struct mcast_snooping;
>  #define MCAST_MROUTER_PORT_IDLE_TIME 180
>
>  /* Multicast group protocol. */
> -typedef enum {
> +enum mcast_group_proto {
>  MCAST_GROUP_IGMPV1 = 0,
>  MCAST_GROUP_IGMPV2,
>  MCAST_GROUP_IGMPV3,
>  MCAST_GROUP_MLDV1,
>  MCAST_GROUP_MLDV2,
> -} mcast_group_proto;
> +};
>
>  /* Multicast group entry.
>   * Guarded by owning 'mcast_snooping''s rwlock. */
> @@ -61,7 +61,7 @@ struct mcast_group {
>  uint16_t vlan;
>
>  /* Multicast group IPv6/IPv4 Protocol version IGMPv1,2,3 or MLDv1,2 */
> -mcast_group_proto protocol_version;
> +enum mcast_group_proto protocol_version;
>
>  /* Node in parent struct mcast_snooping group_lru. */
>  struct ovs_list group_node OVS_GUARDED;
> @@ -198,11 +198,11 @@ mcast_snooping_lookup4(const struct mcast_snooping
> *ms, ovs_be32 ip4,
>  bool mcast_snooping_add_group(struct mcast_snooping *ms,
>const struct in6_addr *addr,
>uint16_t vlan, void *port,
> -  mcast_group_proto grp_proto)
> +  enum mcast_group_proto grp_proto)
>  OVS_REQ_WRLOCK(ms->rwlock);
>  bool mcast_snooping_add_group4(struct mcast_snooping *ms, ovs_be32 ip4,
> uint16_t vlan, void *port,
> -   mcast_group_proto grp_proto)
> +   enum mcast_group_proto grp_proto)
>  OVS_REQ_WRLOCK(ms->rwlock);
>  int mcast_snooping_add_report(struct mcast_snooping *ms,
>const struct dp_packet *p,
> @@ -224,7 +224,7 @@ bool mcast_snooping_add_mrouter(struct mcast_snooping
> *ms, uint16_t vlan,
>  OVS_REQ_WRLOCK(ms->rwlock);
>  bool mcast_snooping_is_query(ovs_be16 igmp_type);
>  bool mcast_snooping_is_membership(ovs_be16 igmp_type);
> -char *mcast_snooping_group_protocol_str(mcast_group_proto grp_proto);
> +char *mcast_snooping_group_protocol_str(enum mcast_group_proto grp_proto);
>
>  /* Flush. */
>  void mcast_snooping_mdb_flush(struct mcast_snooping *ms);
> diff --git a/ofproto/ofproto-dpif-xlate.c b/ofproto/ofproto-dpif-xlate.c
> index f4d1d7194..1cf4d5f7c 100644
> --- a/ofproto/ofproto-dpif-xlate.c
> +++ b/ofproto/ofproto-dp

Re: [ovs-dev] [PATCH ovn] Controller: Handle unconditional IDL messages while paused.

2024-01-25 Thread Mohammad Heib
Hi Mark,

Thank you for your quick review,

On Thu, Jan 25, 2024 at 12:40 AM Mark Michelson  wrote:

> Hi Mohammad,
>
> I'm having a hard time with this one, and mainly it's because of what
> the intended semantics of being "paused" are. I could see it argued that
> pausing ovn-controller should have the existing behavior. I could see
> someone writing a test where they pause ovn-controller specifically to
> trigger disconnection SB DB.
>


>
> My comments below have the mindset that this change is the correct
> behavior. But in addition to my comments, I think we need to verify if
> this proposed change is what we actually want ovn-controller to do.
>
> i agree with you indeed this patch changed the controller behavior a
little bit,
but we need it to handle cases such as BZ [1].

This BZ is affected by similar scenarios that this patch is fixing:
when we have the ovn-controller  in a pause state some pinctrl pkt-in can
be received on the ovn-controller
and pinctrl thread will handle them and save the needed data for SBDB to
temporary storage that will be removed
each controller loop iteration (see run_put_vport_bindings in the pinctrl
for example).
so once the user triggers a resume to the ovn-controller the controller
will try to commit this temporary data
and the TXN will fail and we lose the needed data.

The issue is present even if the controller wasn't on pause but the ovsdb
server is a bit busy and TXN has failed.
i will submit a separate patch to handle vport specific issue when TXN
fails maybe keep the temporary data for a bit longer
using timestamp but i think we must also keep answering the ovsdb server
prob messages to avoid mult-reconnecting from the ovsdb server.

What do you think?


[1] https://bugzilla.redhat.com/show_bug.cgi?id=1954659

On 1/23/24 08:03, Mohammad Heib wrote:
> > If the user triggers a pause command to the ovn-controller the current
> > implementation will wait for commands from unixctl server only and
> > ignore the other component.
> >
> > This implementation works fine if we don't have inactivity_probe set in
> > the SB DataBase, but once the user sets the inactivity_probe in SB
> > DataBase the connection will be dropped by the SBDB. Once the controller
> > resumes the execution it will try to commit some changes to the SBDB but
> > the transaction will fail since we lost the connection to the SBDB and
> > the controller must reconnect before committing the transaction again.
> >
> > To avoid the above scenario the controller can keep handling
> > unconditional IDL messages to avoid reconnecting to SB.
> >
> > Signed-off-by: Mohammad Heib 
> > ---
> >   controller/ovn-controller.c | 16 +---
> >   ovn-sb.xml  |  2 +-
> >   tests/ovn-controller.at | 51 +
> >   3 files changed, 65 insertions(+), 4 deletions(-)
> >
> > diff --git a/controller/ovn-controller.c b/controller/ovn-controller.c
> > index 856e5e270..d2c8f66d9 100644
> > --- a/controller/ovn-controller.c
> > +++ b/controller/ovn-controller.c
> > @@ -5534,12 +5534,22 @@ main(int argc, char *argv[])
> >   simap_destroy();
> >   }
> >
> > -/* If we're paused just run the unixctl server and skip most of
> the
> > - * processing loop.
> > +/* If we're paused just run the unixctl-server/unconditional
> IDL and
> > + *  skip most of the processing loop.
> >*/
> >   if (paused) {
> >   unixctl_server_run(unixctl);
> > +int ovnsb_seq = ovsdb_idl_get_seqno(ovnsb_idl_loop.idl);
> > +ovsdb_idl_run(ovnsb_idl_loop.idl);
> > +int new_ovnsb_seq = ovsdb_idl_get_seqno(ovnsb_idl_loop.idl);
> > +/* If the IDL content has changed while the controller is
> > + * in pause state, trigger a recompute.
> > + */
> > +if (new_ovnsb_seq != ovnsb_seq) {
> > +engine_set_force_recompute(true);
> > +}
>
> If we're going to safeguard ourselves from being disconnected from the
> SB DB, then we should do the same for the OVS DB.
>
> >   unixctl_server_wait(unixctl);
> > +ovsdb_idl_wait(ovnsb_idl_loop.idl);
> >   goto loop_done;
> >   }
> >
> > @@ -6009,7 +6019,6 @@ main(int argc, char *argv[])
> >   OVS_NOT_REACHED();
> >   }
> >
> > -ovsdb_idl_track_clear(ovnsb_idl_loop.idl);
> >   ovsdb_idl_track_clear(ovs_idl_loop.idl);
> >
> >   lflow_cache_run(ctrl_engine_ctx.lflow_cache);
> > @@ -

Re: [ovs-dev] [PATCH ovn v4 4/4] ic/tests: add unit test for ic sync command

2024-01-24 Thread Mohammad Heib
Hi Ales,

On Fri, Jan 12, 2024 at 11:12 AM Ales Musil  wrote:

>
>
> On Tue, Jan 9, 2024 at 2:29 PM Mohammad Heib  wrote:
>
>> add unit test that check validate that sync command
>> sync ISB properly
>>
>> Signed-off-by: Mohammad Heib 
>> ---
>>
>
> Hi Mohammad,
>
> I have a few comments down below.
>
>
>>  tests/ovn-ic.at | 47 +++
>>  1 file changed, 47 insertions(+)
>>
>> diff --git a/tests/ovn-ic.at b/tests/ovn-ic.at
>> index d4c436f84..f55ffa6cd 100644
>> --- a/tests/ovn-ic.at
>> +++ b/tests/ovn-ic.at
>> @@ -1274,3 +1274,50 @@ OVN_CLEANUP_IC([az1], [az2])
>>
>>  AT_CLEANUP
>>  ])
>> +
>> +AT_SETUP([ovn-ic -- sync ISB status to INB])
>> +ovn_init_ic_db
>> +net_add n1
>> +
>> +ovn_start az1
>> +sim_add gw-az1
>> +as gw-az1
>> +
>> +check ovs-vsctl add-br br-phys
>> +ovn_az_attach az1 n1 br-phys 192.168.1.1
>> +check ovs-vsctl set open . external-ids:ovn-is-interconn=true
>> +as az1
>> +
>> +# pause ovn-ic instance
>> +check ovn-appctl -t ic/ovn-ic pause
>> +
>> +# run sync command in the background this commands
>> +# supposed to stuck since ovn-ic is paused.
>> +$(ovn-ic-nbctl --wait=sb sync &)
>>
>
> The extra $() around shouldn't be needed.
>
>
>> +
>> +for i in {1..5}; do
>> +set -- $(ovn-ic-nbctl get ic_nb_global . nb_ic_cfg sb_ic_cfg)
>> +AS_VAR_SET([ic_nb_cfg], [$1])
>> +AS_VAR_SET([ic_sb_cfg], [$2])
>> +if test $ic_nb_cfg -gt $ic_sb_cfg; then
>> +sleep 1
>> +else
>> +break
>> +fi
>> +done
>>
>
> Why not to use OVS_WAIT_UNTIL?
>
>
>> +
>> +# if ic_nb_cfg equal to ic_sb_cfg that mean both zero
>> +# or both 1 which is a not correct and the test must fail.
>> +AT_FAIL_IF([test $ic_nb_cfg == $ic_sb_cfg])
>>
>
> AT_CHECK would be better suited for this.
>
>
>> +
>> +# resume ovn-ic instance
>> +check ovn-appctl -t ic/ovn-ic resume
>> +set -- $(ovn-ic-nbctl get ic_nb_global . nb_ic_cfg sb_ic_cfg)
>>
>
> We should wait after "resume" for the values to settle down.
>
>
>> +AS_VAR_SET([ic_nb_cfg], [$1])
>> +AS_VAR_SET([ic_sb_cfg], [$2])
>> +AT_FAIL_IF([test $ic_nb_cfg != 1])
>> +AT_FAIL_IF([test $ic_nb_cfg != 1])
>>
>
> Same as above, AT_CHECK would be better.
>
>
>> +
>> +OVN_CLEANUP_IC([az1])
>> +AT_CLEANUP
>> +])
>> --
>> 2.34.3
>>
>> ___
>> dev mailing list
>> d...@openvswitch.org
>> https://mail.openvswitch.org/mailman/listinfo/ovs-dev
>>
>>
> The test seems to be overly complicated for what it tries to achieve. I
> would suggest the following diff:
>
Thank you so much for reviewing the patch,
I agree with you the test is complicated, I will go with your suggestions
in v5,
Thanks :)

>
> diff --git a/tests/ovn-ic.at b/tests/ovn-ic.at
> index f55ffa6cd..32df3be2c 100644
> --- a/tests/ovn-ic.at
> +++ b/tests/ovn-ic.at
> @@ -1293,30 +1293,25 @@ check ovn-appctl -t ic/ovn-ic pause
>
>  # run sync command in the background this commands
>  # supposed to stuck since ovn-ic is paused.
> -$(ovn-ic-nbctl --wait=sb sync &)
> -
> -for i in {1..5}; do
> -set -- $(ovn-ic-nbctl get ic_nb_global . nb_ic_cfg sb_ic_cfg)
> -AS_VAR_SET([ic_nb_cfg], [$1])
> -AS_VAR_SET([ic_sb_cfg], [$2])
> -if test $ic_nb_cfg -gt $ic_sb_cfg; then
> -sleep 1
> -else
> -break
> -fi
> -done
> +ovn-ic-nbctl --wait=sb sync &
>
> -# if ic_nb_cfg equal to ic_sb_cfg that mean both zero
> -# or both 1 which is a not correct and the test must fail.
> -AT_FAIL_IF([test $ic_nb_cfg == $ic_sb_cfg])
> +OVS_WAIT_UNTIL([test $(ovn-ic-nbctl get ic_nb_global . nb_ic_cfg) -gt
> $(ovn-ic-nbctl get ic_nb_global . sb_ic_cfg)])
> +AT_CHECK([ovn-ic-nbctl get ic_nb_global . nb_ic_cfg], [0], [dnl
> +1
> +])
> +AT_CHECK([ovn-ic-nbctl get ic_nb_global . sb_ic_cfg], [0], [dnl
> +0
> +])
>
>  # resume ovn-ic instance
>  check ovn-appctl -t ic/ovn-ic resume
> -set -- $(ovn-ic-nbctl get ic_nb_global . nb_ic_cfg sb_ic_cfg)
> -AS_VAR_SET([ic_nb_cfg], [$1])
> -AS_VAR_SET([ic_sb_cfg], [$2])
> -AT_FAIL_IF([test $ic_nb_cfg != 1])
> -AT_FAIL_IF([test $ic_nb_cfg != 1])
> +OVS_WAIT_UNTIL([test $(ovn-ic-nbctl get ic_nb_global . nb_ic_cfg) -eq
> $(ovn-ic-nbctl get ic_nb_global . sb_ic_cfg)])
> +AT_CHECK([ovn-ic-nbctl get ic_nb_global . nb_ic_cfg], [0], [dnl
> +1
> +])
> +AT_CHECK([ovn-ic-nbctl get ic_nb_global . sb_ic_cfg], [0], [dnl
> +1
> +])
>
>  OVN_CLEANUP_IC([az1])
>  AT_CLEANUP
>
>
> Thanks,
> Ales
>
> --
>
> Ales Musil
>
> Senior Software Engineer - OVN Core
>
> Red Hat EMEA <https://www.redhat.com>
>
> amu...@redhat.com
> <https://red.ht/sig>
>
___
dev mailing list
d...@openvswitch.org
https://mail.openvswitch.org/mailman/listinfo/ovs-dev


[ovs-dev] [PATCH ovn v5 3/4] OVN-IC: Make it possible for CMS to detect when the ISB is up-to-date.

2024-01-24 Thread Mohammad Heib
Until now, there has been no reliable for the CMS to detect when
changes made to the INB configuration have been passed through
to the ISB, This commit adds this feature to the system,
by adding sequence numbers to the INB and ISB and adding code
in ovn-ic-nbctl, ovn-ic to keep those sequence numbers up-to-date.

The biggest user-visible change from this commit is a new option
'--wait' and new command 'sync' to ovn-ic-nbctl.
With --wait=sb, ovn-ic-nbctl now waits for ovn-ics to update the ISB
database.

Signed-off-by: Mohammad Heib 
Acked-by: Mark Michelson 
Acked-by: Ales Musil 
---
 utilities/ovn-ic-nbctl.8.xml | 49 
 utilities/ovn-ic-nbctl.c | 86 +++-
 2 files changed, 133 insertions(+), 2 deletions(-)

diff --git a/utilities/ovn-ic-nbctl.8.xml b/utilities/ovn-ic-nbctl.8.xml
index 4a70994b8..5a1324d2d 100644
--- a/utilities/ovn-ic-nbctl.8.xml
+++ b/utilities/ovn-ic-nbctl.8.xml
@@ -123,9 +123,58 @@
   
 
 
+Synchronization Commands
+
+
+  sync
+  
+Ordinarily, --wait=sb only waits for changes by the
+current ovn-ic-nbctl invocation to take effect.
+This means that, if none of the commands supplied to
+ovn-ic-nbctl change the database, then the command does
+not wait at all.  With the sync command, however,
+ovn-ic-nbctl waits even for earlier changes to the
+database to propagate down to the southbound database, according to the
+argument of --wait.
+  
+
+
 Options
 
 
+  --no-wait | --wait=none
+  --wait=sb
+
+  
+
+  These options control whether and how ovn-ic-nbctl waits
+  for the OVN system to become up-to-date with changes made in an
+  ovn-ic-nbctl invocation.
+
+
+
+  By default, or if --no-wait or --wait=none,
+  ovn-ic-nbctl exits immediately after confirming that
+  changes have been committed to the Interconnect northbound database,
+  without waiting.
+
+
+
+  With --wait=sb, before ovn-ic-nbctl exits,
+  it waits for ovn-ics to bring the Interconnect
+  southbound database up-to-date with the Interconnect northbound
+  database updates.
+
+
+
+  Ordinarily, --wait=sb only waits for changes by the
+  current ovn-ic-nbctl invocation to take effect.
+  This means that, if none of the commands supplied to
+  ovn-ic-nbctl change the database, then the command
+  does not wait at all.
+  Use the sync command to override this behavior.
+
+  
 --db database
 
   The OVSDB database remote to contact.  If the OVN_IC_NB_DB
diff --git a/utilities/ovn-ic-nbctl.c b/utilities/ovn-ic-nbctl.c
index 721dc4586..4317c385a 100644
--- a/utilities/ovn-ic-nbctl.c
+++ b/utilities/ovn-ic-nbctl.c
@@ -58,6 +58,13 @@ static bool oneline;
 /* --dry-run: Do not commit any changes. */
 static bool dry_run;
 
+/* --wait=TYPE: Wait for configuration change to take effect? */
+static enum nbctl_wait_type wait_type = NBCTL_WAIT_NONE;
+
+/* Should we wait (if specified by 'wait_type') even if the commands don't
+ * change the database at all */
+static bool force_wait = false;
+
 /* --timeout: Time to wait for a connection to 'db'. */
 static unsigned int timeout;
 
@@ -161,6 +168,8 @@ parse_options(int argc, char *argv[], struct shash 
*local_options)
 OPT_DB = UCHAR_MAX + 1,
 OPT_ONELINE,
 OPT_NO_SYSLOG,
+OPT_NO_WAIT,
+OPT_WAIT,
 OPT_DRY_RUN,
 OPT_LOCAL,
 OPT_COMMANDS,
@@ -173,6 +182,8 @@ parse_options(int argc, char *argv[], struct shash 
*local_options)
 static const struct option global_long_options[] = {
 {"db", required_argument, NULL, OPT_DB},
 {"no-syslog", no_argument, NULL, OPT_NO_SYSLOG},
+{"no-wait", no_argument, NULL, OPT_NO_WAIT},
+{"wait", required_argument, NULL, OPT_WAIT},
 {"dry-run", no_argument, NULL, OPT_DRY_RUN},
 {"oneline", no_argument, NULL, OPT_ONELINE},
 {"timeout", required_argument, NULL, 't'},
@@ -234,7 +245,19 @@ parse_options(int argc, char *argv[], struct shash 
*local_options)
 case OPT_DRY_RUN:
 dry_run = true;
 break;
-
+case OPT_NO_WAIT:
+wait_type = NBCTL_WAIT_NONE;
+break;
+case OPT_WAIT:
+if (!strcmp(optarg, "none")) {
+wait_type = NBCTL_WAIT_NONE;
+} else if (!strcmp(optarg, "sb")) {
+wait_type = NBCTL_WAIT_SB;
+} else {
+ctl_fatal("argument to --wait must be "
+  "\"none\", \"sb\" ");
+}
+break;
 case OPT_LOCAL:
 if (shash_fin

[ovs-dev] [PATCH ovn v5 4/4] ic/tests: Add unit test for ic sync command.

2024-01-24 Thread Mohammad Heib
add unit test that check validate that sync command
sync ISB properly

Signed-off-by: Mohammad Heib 
---
 tests/ovn-ic.at | 43 +++
 1 file changed, 43 insertions(+)

diff --git a/tests/ovn-ic.at b/tests/ovn-ic.at
index d4c436f84..535aba7da 100644
--- a/tests/ovn-ic.at
+++ b/tests/ovn-ic.at
@@ -1274,3 +1274,46 @@ OVN_CLEANUP_IC([az1], [az2])
 
 AT_CLEANUP
 ])
+
+OVN_FOR_EACH_NORTHD([
+AT_SETUP([ovn-ic -- sync ISB status to INB])
+ovn_init_ic_db
+net_add n1
+
+ovn_start az1
+sim_add gw-az1
+as gw-az1
+
+check ovs-vsctl add-br br-phys
+ovn_az_attach az1 n1 br-phys 192.168.1.1
+check ovs-vsctl set open . external-ids:ovn-is-interconn=true
+as az1
+
+# pause ovn-ic instance
+check ovn-appctl -t ic/ovn-ic pause
+
+# run sync command in the background this commands
+# supposed to stuck since ovn-ic is paused.
+ovn-ic-nbctl --wait=sb sync &
+
+OVS_WAIT_UNTIL([test $(ovn-ic-nbctl get ic_nb_global . nb_ic_cfg) -gt 
$(ovn-ic-nbctl get ic_nb_global . sb_ic_cfg)])
+AT_CHECK([ovn-ic-nbctl get ic_nb_global . nb_ic_cfg], [0], [dnl
+1
+])
+AT_CHECK([ovn-ic-nbctl get ic_nb_global . sb_ic_cfg], [0], [dnl
+0
+])
+
+# resume ovn-ic instance
+check ovn-appctl -t ic/ovn-ic resume
+OVS_WAIT_UNTIL([test $(ovn-ic-nbctl get ic_nb_global . nb_ic_cfg) -eq 
$(ovn-ic-nbctl get ic_nb_global . sb_ic_cfg)])
+AT_CHECK([ovn-ic-nbctl get ic_nb_global . nb_ic_cfg], [0], [dnl
+1
+])
+AT_CHECK([ovn-ic-nbctl get ic_nb_global . sb_ic_cfg], [0], [dnl
+1
+])
+
+OVN_CLEANUP_IC([az1])
+AT_CLEANUP
+])
-- 
2.34.3

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


[ovs-dev] [PATCH ovn v5 2/4] ovn-ic: Implement basic INB change handling status.

2024-01-24 Thread Mohammad Heib
This patch implements a basic sequence number protocol
that can be used by CMS to determine if the changes
applied to INB are successfully propagated to ISB.

The implementation of this patch relies on OVN-ICs
instances to update the ISB by adding a per AZ a nb_ic_cfg
counter that will be updated by the OVN-IC once it is done
and commit all needed changes to the ISB, and according to this
AZ:nb_ic_cfg the ISB and INB will be updating about the status
of the changes.

Signed-off-by: Mohammad Heib 
---
 ic/ovn-ic.c | 95 ++---
 1 file changed, 90 insertions(+), 5 deletions(-)

diff --git a/ic/ovn-ic.c b/ic/ovn-ic.c
index 8ceb34d7c..d0b58d4d1 100644
--- a/ic/ovn-ic.c
+++ b/ic/ovn-ic.c
@@ -1782,16 +1782,95 @@ route_run(struct ic_context *ctx,
 hmap_destroy(_lrs);
 }
 
+/*
+ * This function implements a sequence number protocol that can be used by
+ * the INB end user to verify that ISB is synced with all the changes that
+ * are done be the user/AZs-controllers:
+ *
+ * Since we have multiple IC instances running in different regions
+ * we can't rely on one of them to update the ISB and sync that update
+ * to INB since other ICs can make changes in parallel.
+ * So to have a sequence number protocol working properly we must
+ * make sure that all the IC instances are synced with the ISB first
+ * and then update the INB.
+ *
+ * To guarantee that all instances are synced with ISB first, each IC
+ * will do the following steps:
+ *
+ * 1. when local ovn-ic sees that INB:nb_ic_cfg has updated we will set
+ *the ic_sb_loop->next_cfg to match the INB:nb_ic_cfg and increment
+ *the value of AZ:nb_ic_cfg and wait until we get confirmation from
+ *the server.
+ *
+ * 2. once this IC instance changes for ISB are committed successfully
+ *(next loop), the value of cur_cfg will be updated to match
+ *the INB:nb_ic_cfg that indicate that our local instance is up to date
+ *and no more changes need to be done for ISB.
+ *
+ * 3. validate that the AZ:nb_ic_cfg to match the INB:nb_ic_cfg.
+ *
+ * 4. Go through all the AZs and check if all have the same value of
+ *AZ:nb_ic_cfg that means all the AZs are done with ISB changes and ISB are
+ *up to date with INB, so we can set the values of ISB:nb_ic_cfg to
+ *INB:nb_ic_cfg and INB:sb_ic_cfg to INB:nb_ic_cfg.
+ */
 static void
-ovn_db_run(struct ic_context *ctx)
+update_sequence_numbers(const struct icsbrec_availability_zone *az,
+struct ic_context *ctx,
+struct ovsdb_idl_loop *ic_sb_loop)
 {
-const struct icsbrec_availability_zone *az = az_run(ctx);
-VLOG_DBG("Availability zone: %s", az ? az->name : "not created yet.");
+if (!ctx->ovnisb_txn || !ctx->ovninb_txn) {
+return;
+}
+
+const struct icnbrec_ic_nb_global *ic_nb = icnbrec_ic_nb_global_first(
+   ctx->ovninb_idl);
+if (!ic_nb) {
+ic_nb = icnbrec_ic_nb_global_insert(ctx->ovninb_txn);
+}
+const struct icsbrec_ic_sb_global *ic_sb = icsbrec_ic_sb_global_first(
+   ctx->ovnisb_idl);
+if (!ic_sb) {
+ic_sb = icsbrec_ic_sb_global_insert(ctx->ovnisb_txn);
+}
 
-if (!az) {
+if ((ic_nb->nb_ic_cfg != ic_sb->nb_ic_cfg) &&
+  (ic_nb->nb_ic_cfg != az->nb_ic_cfg)) {
+/* Deal with potential overflows. */
+if (az->nb_ic_cfg == LLONG_MAX) {
+icsbrec_availability_zone_set_nb_ic_cfg(az, 0);
+}
+ic_sb_loop->next_cfg = ic_nb->nb_ic_cfg;
+ovsdb_idl_txn_increment(ctx->ovnisb_txn, >header_,
+   _availability_zone_col_nb_ic_cfg, true);
 return;
 }
 
+/* handle cases where accidentally AZ:ic_nb_cfg exceeds
+ * the INB:ic_nb_cfg.
+ */
+if (az->nb_ic_cfg != ic_sb_loop->cur_cfg) {
+icsbrec_availability_zone_set_nb_ic_cfg(az, ic_sb_loop->cur_cfg);
+return;
+}
+
+const struct icsbrec_availability_zone *other_az;
+ICSBREC_AVAILABILITY_ZONE_FOR_EACH (other_az, ctx->ovnisb_idl) {
+if (other_az->nb_ic_cfg != az->nb_ic_cfg) {
+return;
+}
+}
+/* All the AZs are updated successfully, update SB/NB counter. */
+if (ic_nb->nb_ic_cfg != ic_sb->nb_ic_cfg) {
+icsbrec_ic_sb_global_set_nb_ic_cfg(ic_sb, az->nb_ic_cfg);
+icnbrec_ic_nb_global_set_sb_ic_cfg(ic_nb, az->nb_ic_cfg);
+}
+}
+
+static void
+ovn_db_run(struct ic_context *ctx,
+   const struct icsbrec_availability_zone *az)
+{
 ts_run(ctx);
 gateway_run(ctx, az);
 port_binding_run(ctx, az);
@@ -2218,7 +2297,13 @@ main(int argc, char *argv[])
 ovsdb_idl_has_ever_connected(ctx.ovnsb_idl) &&
 ovsdb_idl_has_ever_connected(ctx.ovninb_idl) &

[ovs-dev] [PATCH ovn v5 1/4] OVN-IC: Interconnect DBs add basic Information Flow columns.

2024-01-24 Thread Mohammad Heib
Add basic flow columns to interconnect northbound DB and
interconnect Southbound DB.

Those columns will be used by future patches to add basic
support for Information Flow in OVN  interconnect.

Signed-off-by: Mohammad Heib 
Acked-by: Mark Michelson 
Acked-by: Ales Musil 
---
 NEWS|  8 
 ovn-ic-nb.ovsschema |  6 --
 ovn-ic-nb.xml   | 17 +
 ovn-ic-sb.ovsschema |  8 +---
 ovn-ic-sb.xml   | 21 +
 5 files changed, 55 insertions(+), 5 deletions(-)

diff --git a/NEWS b/NEWS
index 5f267b4c6..9762af0e6 100644
--- a/NEWS
+++ b/NEWS
@@ -14,6 +14,14 @@ Post v23.09.0
   - ovn-northd-ddlog has been removed.
   - A new LSP option "enable_router_port_acl" has been added to enable
 conntrack for the router port whose peer is l3dgw_port if set it true.
+  - OVN Interconnection:
+* INB provides basic feedback to the CMS about the ISB changes
+  handling status.
+* IC_NB_Global now have "nb_ic_cfg" and "sb_ic_cfg" columns for
+  for ISB informational status.
+* IC_SB_Global now have "nb_ic_cfg" column for ISB informational status.
+* Availability_Zone now have "nb_ic_cfg" column for local AZ
+  informational status.
 
 OVN v23.09.0 - 15 Sep 2023
 --
diff --git a/ovn-ic-nb.ovsschema b/ovn-ic-nb.ovsschema
index 894db8344..bee174357 100644
--- a/ovn-ic-nb.ovsschema
+++ b/ovn-ic-nb.ovsschema
@@ -1,10 +1,12 @@
 {
 "name": "OVN_IC_Northbound",
-"version": "1.0.0",
-"cksum": "45589876 3383",
+"version": "1.1.0",
+"cksum": "3964083684 3501",
 "tables": {
 "IC_NB_Global": {
 "columns": {
+"nb_ic_cfg": {"type": {"key": "integer"}},
+"sb_ic_cfg": {"type": {"key": "integer"}},
 "external_ids": {
 "type": {"key": "string", "value": "string",
  "min": 0, "max": "unlimited"}},
diff --git a/ovn-ic-nb.xml b/ovn-ic-nb.xml
index 8c53bec3b..2ae9bf6d5 100644
--- a/ovn-ic-nb.xml
+++ b/ovn-ic-nb.xml
@@ -36,6 +36,23 @@
   one row.
 
 
+
+  These columns allow a client to track the overall configuration state of
+  the system.
+
+  
+Sequence number for client to increment. When a client modifies the
+interconnect northbound database configuration and wishes to wait for
+OVN-ICs to handle this change and update the Interconnect
+southbound database, it may increment this sequence number.
+  
+  
+Sequence number that one OVN-IC sets to the value of
+ after waiting to all the OVN-ICs
+finish applying their changes to interconnect southbound database.
+  
+
+
 
   
 See External IDs at the beginning of this document.
diff --git a/ovn-ic-sb.ovsschema b/ovn-ic-sb.ovsschema
index 1d60b36d1..5baf141cf 100644
--- a/ovn-ic-sb.ovsschema
+++ b/ovn-ic-sb.ovsschema
@@ -1,10 +1,11 @@
 {
 "name": "OVN_IC_Southbound",
-"version": "1.1.1",
-"cksum": "3684563024 6914",
+"version": "1.2.0",
+"cksum": "1381014956 7032",
 "tables": {
 "IC_SB_Global": {
 "columns": {
+"nb_ic_cfg": {"type": {"key": "integer"}},
 "external_ids": {
 "type": {"key": "string", "value": "string",
  "min": 0, "max": "unlimited"}},
@@ -24,7 +25,8 @@
 "isRoot": true},
 "Availability_Zone": {
 "columns": {
-"name": {"type": "string"}},
+"name": {"type": "string"},
+"nb_ic_cfg": {"type": {"key": "integer"}}},
 "isRoot": true,
 "indexes": [["name"]]},
 "Gateway": {
diff --git a/ovn-ic-sb.xml b/ovn-ic-sb.xml
index f7e17e113..c3e7d2173 100644
--- a/ovn-ic-sb.xml
+++ b/ovn-ic-sb.xml
@@ -69,6 +69,21 @@
   one row.
 
 
+
+  This column allow a client to track the overall configuration state of
+  the system.
+
+  
+Sequence number for the configuration. When a CMS or
+ovn-ic-nbctl updates the Interconnect northbound database,
+it increments the nb_ic_cfg column in the
+NB_IC_Global table in the Interconnect northbound
+database. when OVN-ICs updates the southbound database to
+bring it up to date with these changes, one OVN-IC updates
+this column to the same value.
+  
+
+
 
   
 See External IDs at the beginning of this document.
@@ -102,6 +117,12 @@
 
   A name that uniquely identifies the availability zone.
 
+
+
+  This column is used by the OVN-IC to inform
+  that this IC instance is aligned with the changes in INB
+
+
   
 
   
-- 
2.34.3

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


[ovs-dev] [PATCH ovn v5 0/4] OVN-IC: Add basic sequence number status support.

2024-01-24 Thread Mohammad Heib
Currently, OVN-IC doesn't support a way to tell the end-user when their changes
to the IC-NB database have propagated successfully to the IC-SB Database.

This patch series adds basic support for the sequence number status protocol
that is implemented on the native OVN, with this patch series the end user
now can wait for their changes in the IC-NB DB to take effect by executing the
'sync' command after applying any changes to the IC-NB DB, for example, if the
end-user has created a transit switch in the IC-NB global DB and want to make
sure that the IC-SB create a DP binding for this ts-switch the user now can use
the 'sync' command as following:
$ ovn-ic-nbctl ts-add ts1
$ ovn-ic-nbctl --wait=sb sync

The second command will wait until all the ovn-ic instances see the new changes
and update their own local dbs and the global IC-SB db.

v4 -> v5

* Addressed review comments from Ales to simplify the unit test and
* a small comment on the ovn-ic.
v3 -> v4

* Addressed review comments from Ales to add check for the 
  overflow cases.

v2 -> v3

* Rebase over main.
* Addressed review comments from Mark and Ales.



Mohammad Heib (4):
  OVN-IC: Interconnect DBs add basic Information Flow columns.
  ovn-ic: Implement basic INB change handling status.
  OVN-IC: Make it possible for CMS to detect when the ISB is up-to-date.
  ic/tests: Add unit test for ic sync command.

 NEWS |  8 +++
 ic/ovn-ic.c  | 95 ++--
 ovn-ic-nb.ovsschema  |  6 ++-
 ovn-ic-nb.xml| 17 +++
 ovn-ic-sb.ovsschema  |  8 +--
 ovn-ic-sb.xml| 21 
 tests/ovn-ic.at  | 43 
 utilities/ovn-ic-nbctl.8.xml | 49 +++
 utilities/ovn-ic-nbctl.c | 86 +++-
 9 files changed, 321 insertions(+), 12 deletions(-)

-- 
2.34.3

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


Re: [ovs-dev] [PATCH ovn v4 0/4] OVN-IC: add basic sequence number status support

2024-01-24 Thread Mohammad Heib
Hi Ales,

Yes sure that's what I'm planning to do next, i first wanted to make those
patches accepted upstream and then update the test case to use
the sync command, i guess it will be easier to review if  send the test
cases change as a separate patch, what do you think?

On Fri, Jan 12, 2024 at 11:14 AM Ales Musil  wrote:

>
>
> On Tue, Jan 9, 2024 at 2:29 PM Mohammad Heib  wrote:
>
>> Currently, OVN-IC doesn't support a way to tell the end-user when their
>> changes
>> to the IC-NB database have propagated successfully to the IC-SB Database.
>>
>> This patch series adds basic support for the sequence number status
>> protocol
>> that is implemented on the native OVN, with this patch series the end user
>> now can wait for their changes in the IC-NB DB to take effect by
>> executing the
>> 'sync' command after applying any changes to the IC-NB DB, for example,
>> if the
>> end-user has created a transit switch in the IC-NB global DB and want to
>> make
>> sure that the IC-SB create a DP binding for this ts-switch the user now
>> can use
>> the 'sync' command as following:
>> $ ovn-ic-nbctl ts-add ts1
>> $ ovn-ic-nbctl --wait=sb sync
>>
>> The second command will wait until all the ovn-ic instances see the new
>> changes
>> and update their own local dbs and the global IC-SB db.
>>
>> v3 -> v4
>> 
>> * Addressed review comments from Ales to add check for the
>>   overflow cases.
>>
>> v2 -> v3
>> 
>> * Rebase over main.
>> * Addressed review comments from Mark and Ales.
>>
>>
>> Mohammad Heib (4):
>>   OVN-IC: interconnect DBs add basic Information Flow columns
>>   ovn-ic: implement basic INB change handling status
>>   OVN-IC: Make it possible for CMS to detect when the ISB is up-to-date.
>>   ic/tests: add unit test for ic sync command
>>
>>  NEWS |  8 +++
>>  ic/ovn-ic.c  | 96 ++--
>>  ovn-ic-nb.ovsschema  |  6 ++-
>>  ovn-ic-nb.xml| 17 +++
>>  ovn-ic-sb.ovsschema  |  8 +--
>>  ovn-ic-sb.xml| 21 
>>  tests/ovn-ic.at  | 47 ++
>>  utilities/ovn-ic-nbctl.8.xml | 49 ++
>>  utilities/ovn-ic-nbctl.c | 89 -
>>  9 files changed, 329 insertions(+), 12 deletions(-)
>>
>> --
>> 2.34.3
>>
>> ___
>> dev mailing list
>> d...@openvswitch.org
>> https://mail.openvswitch.org/mailman/listinfo/ovs-dev
>>
>>
> Hi Mohammad,
>
> thank you for the series. This suggestion is out of scope of this series,
> but it would be great to use the new sync across all ic tests that we
> currently have to further stabilize them. WDYT?
>
> Thanks,
> Ales
>
>
> --
>
> Ales Musil
>
> Senior Software Engineer - OVN Core
>
> Red Hat EMEA <https://www.redhat.com>
>
> amu...@redhat.com
> <https://red.ht/sig>
>
___
dev mailing list
d...@openvswitch.org
https://mail.openvswitch.org/mailman/listinfo/ovs-dev


Re: [ovs-dev] [PATCH ovn 2/2] OVN-SB: Exposes igmp group protocol version through IGMP table.

2024-01-23 Thread Mohammad Heib
On Tue, Jan 23, 2024 at 4:10 PM Dumitru Ceara  wrote:

> On 1/23/24 14:58, Mohammad Heib wrote:
> >>>  static struct pinctrl pinctrl;
> >>> @@ -3586,11 +3587,21 @@ pinctrl_update(const struct ovsdb_idl *idl,
> >> const char *br_int_name)
> >>>  if (dns_supports_ovn_owned != pinctrl.dns_supports_ovn_owned) {
> >>>  pinctrl.dns_supports_ovn_owned = dns_supports_ovn_owned;
> >>>
> >>> -/* Notify pinctrl_handler that fdb timestamp column
> >>> +/* Notify pinctrl_handler that dns ovn_owned column
> >>> * availability has changed. */
> >>>  notify_pinctrl_handler();
> >>>  }
> >>>
> >>> +bool igmp_support_proto =
> >>> +sbrec_server_has_igmp_group_table_col_protocol(idl);
> >>> +if (igmp_support_proto != pinctrl.igmp_support_protocol) {
> >>> +pinctrl.igmp_support_protocol = igmp_support_proto;
> >> We only use this in the main thread, when updating the SB, why can't we
> >> just directly check the column support there instead?
> >>
> > *like you mean to call
> > sbrec_server_has_igmp_group_table_col_protocol(idl); inside the
> **ip_mcast_sync
> > function?*
> > *something like this:*
> >
> >
> >
> >
> > */* Set Group protocol*/if
> > (sbrec_server_has_igmp_group_table_col_protocol(idl)) {
> > igmp_group_set_protocol(sbrec_igmp,
> > mc_group->protocol_version);}*
>
> Yes, I think that would be better.  Or even inside
> igmp_group_update_ports() but then we should also pass the IDL pointer;
> the latter seems like a better option to me.
>
> Please let me know what you think.
>
Sound good to me :),
i will send v2 addressing your comments when I can bump the ovs to the last
stable.

Thank you so much :)

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


Re: [ovs-dev] [PATCH ovn 2/2] OVN-SB: Exposes igmp group protocol version through IGMP table.

2024-01-23 Thread Mohammad Heib
On Mon, Jan 22, 2024 at 5:26 PM Dumitru Ceara  wrote:

> On 1/22/24 15:14, Mohammad Heib wrote:
> > Expose the igmp/mld group protocol version through the
> > IGMP_GROUP table in SBDB.
> >
> > This patch can be used by ovn consumer for debuggability purposes, user
> > now can  match between the protocol version used in the OVN logical
> > switches and the uplink ports.
> >
> > Rreported-at: https://bugzilla.redhat.com/show_bug.cgi?id=2160476
> > Signed-off-by: Mohammad Heib 
> > ---
>
Hi Dumitru,
Thank you for your review :), i have small question please see below.


> Hi Mohammad,
>
> I have a few (minor) comments, please see below.
>
> >  NEWS  |  2 ++
> >  controller/ip-mcast.c |  8 
> >  controller/ip-mcast.h |  3 +++
> >  controller/pinctrl.c  | 19 ++-
> >  northd/ovn-northd.c   |  2 +-
> >  ovn-sb.ovsschema  |  5 +++--
> >  ovn-sb.xml|  4 
> >  tests/ovn.at  |  3 +++
> >  8 files changed, 42 insertions(+), 4 deletions(-)
> >
> > diff --git a/NEWS b/NEWS
> > index 5f267b4c6..9075e7d80 100644
> > --- a/NEWS
> > +++ b/NEWS
> > @@ -14,6 +14,8 @@ Post v23.09.0
> >- ovn-northd-ddlog has been removed.
> >- A new LSP option "enable_router_port_acl" has been added to enable
> >  conntrack for the router port whose peer is l3dgw_port if set it
> true.
> > +  - IGMP_Group have a new "protocol" column that displays the the group
>
> Nit: s/have/has
>
> > +protocol version.
> >
> >  OVN v23.09.0 - 15 Sep 2023
> >  --
> > diff --git a/controller/ip-mcast.c b/controller/ip-mcast.c
> > index a870fb29e..83e41c81f 100644
> > --- a/controller/ip-mcast.c
> > +++ b/controller/ip-mcast.c
> > @@ -226,6 +226,14 @@ igmp_group_cleanup(struct ovsdb_idl_txn
> *ovnsb_idl_txn,
> >  return true;
> >  }
> >
> > +
> > +void igmp_group_set_protocol(const struct sbrec_igmp_group *group,
> > + mcast_group_proto protocol)
> > +{
> > +sbrec_igmp_group_set_protocol(group,
> > +
> mcast_snooping_group_protocol_str(protocol));
> > +}
> > +
>
> Does it make more sense to add the protocol as argument to
> igmp_group_update_ports() and rename that function to igmp_group_update()?
>
yes that make sense and will make the code more cleaner.

>
> >  static const struct sbrec_igmp_group *
> >  igmp_group_lookup_(struct ovsdb_idl_index *igmp_groups,
> > const char *addr_str,
> > diff --git a/controller/ip-mcast.h b/controller/ip-mcast.h
> > index 326f39db1..f0c34343f 100644
> > --- a/controller/ip-mcast.h
> > +++ b/controller/ip-mcast.h
> > @@ -63,4 +63,7 @@ void igmp_group_delete(const struct sbrec_igmp_group
> *g);
> >  bool igmp_group_cleanup(struct ovsdb_idl_txn *ovnsb_idl_txn,
> >  struct ovsdb_idl_index *igmp_groups);
> >
> > +void igmp_group_set_protocol(const struct sbrec_igmp_group *group,
> > + mcast_group_proto protocol);
> > +
> >  #endif /* controller/ip-mcast.h */
> > diff --git a/controller/pinctrl.c b/controller/pinctrl.c
> > index 77bf67e58..6379b7afb 100644
> > --- a/controller/pinctrl.c
> > +++ b/controller/pinctrl.c
> > @@ -180,6 +180,7 @@ struct pinctrl {
> >  bool mac_binding_can_timestamp;
> >  bool fdb_can_timestamp;
> >  bool dns_supports_ovn_owned;
> > +bool igmp_support_protocol;
> >  };
> >
> >  static struct pinctrl pinctrl;
> > @@ -3586,11 +3587,21 @@ pinctrl_update(const struct ovsdb_idl *idl,
> const char *br_int_name)
> >  if (dns_supports_ovn_owned != pinctrl.dns_supports_ovn_owned) {
> >  pinctrl.dns_supports_ovn_owned = dns_supports_ovn_owned;
> >
> > -/* Notify pinctrl_handler that fdb timestamp column
> > +/* Notify pinctrl_handler that dns ovn_owned column
> > * availability has changed. */
> >  notify_pinctrl_handler();
> >  }
> >
> > +bool igmp_support_proto =
> > +sbrec_server_has_igmp_group_table_col_protocol(idl);
> > +if (igmp_support_proto != pinctrl.igmp_support_protocol) {
> > +pinctrl.igmp_support_protocol = igmp_support_proto;
>
> We only use this in the main thread, when updating the SB, why can't we
> just directly check the column support there instead?
>
*like you mean to call
sbrec_server_has_igmp_group_table_col_protocol(idl); in

Re: [ovs-dev] [PATCH ovn 1/2] ovs: Bump submodule to include igmp protocol version.

2024-01-23 Thread Mohammad Heib
Hi Dumitru,

Thank you for the review,
yes sure will bump the submodule to the last stable once they fix the issue.
Thanks

On Mon, Jan 22, 2024 at 5:01 PM Dumitru Ceara  wrote:

> On 1/22/24 15:14, Mohammad Heib wrote:
> > Specifically the following commit:
> >   077d0bad0436 ("mcast-snooping: Store IGMP/MLD protocol version.")
> >
> > Also fix a small compilation error due to prototype change.
> >
> > Signed-off-by: Mohammad Heib 
> > ---
>
> Hi Mohammad,
>
> Thanks for the patch!
>
> >  controller/pinctrl.c | 6 +-
> >  ovs  | 2 +-
> >  2 files changed, 6 insertions(+), 2 deletions(-)
> >
> > diff --git a/controller/pinctrl.c b/controller/pinctrl.c
> > index 4992eab08..77bf67e58 100644
> > --- a/controller/pinctrl.c
> > +++ b/controller/pinctrl.c
> > @@ -5474,9 +5474,13 @@ pinctrl_ip_mcast_handle_igmp(struct rconn *swconn,
> >  switch (ntohs(ip_flow->tp_src)) {
> >  case IGMP_HOST_MEMBERSHIP_REPORT:
> >  case IGMPV2_HOST_MEMBERSHIP_REPORT:
> > +mcast_group_proto grp_proto =
> > +(ntohs(ip_flow->tp_src) == IGMP_HOST_MEMBERSHIP_REPORT)
> > +? MCAST_GROUP_IGMPV1
> > +: MCAST_GROUP_IGMPV2;
> >  group_change =
> >  mcast_snooping_add_group4(ip_ms->ms, ip4, IP_MCAST_VLAN,
> > -  port_key_data);
> > +  port_key_data, grp_proto);
> >  break;
> >  case IGMP_HOST_LEAVE_MESSAGE:
> >  group_change =
> > diff --git a/ovs b/ovs
> > index 4102674b3..b222593bc 16
> > --- a/ovs
> > +++ b/ovs
> > @@ -1 +1 @@
> > -Subproject commit 4102674b3ecadb0e20e512cc661cddbbc4b3d1f6
> > +Subproject commit b222593bc69b5d82849d18eb435564f5f93449d3
>
> However, it's probably desirable to bump the submodule to the tip of the
> latest stable branch, i.e. branch-3.3:
>
>
> https://github.com/ovn-org/ovn/blob/main/Documentation/internals/ovs_submodule.rst#submodules-for-releases
>
> That would also fix our scheduled CI runs:
>
> https://github.com/ovn-org/ovn/actions/runs/7597582431/job/20692570222#step:10:3531
>
> However, there's a crash in OVS on branch-3.3 that needs to be fixed first:
> https://issues.redhat.com/browse/FDP-300
>
> I'd wait with bumping the submodule until then.
>
> Regards,
> Dumitru
>
>
___
dev mailing list
d...@openvswitch.org
https://mail.openvswitch.org/mailman/listinfo/ovs-dev


[ovs-dev] [PATCH ovn v2] ovn-ic: Handle NB:name updates properly.

2024-01-23 Thread Mohammad Heib
When the user updates the NB_GLOBAL.name after registering
to IC Databases if the user already has defined chassis as a gateway
that will cause ovn-ic instance to run in an infinity loop trying
to update the gateways and insert the current gateway to the SB.chassis
tables as a remote chassis (we match on the new AZ ) which will fail since
we already have this chassis with is-interconn in local SB.

This patch aims to fix the above issues by updating the AZ.name only
when the user updates the NB.name locally.

Signed-off-by: Mohammad Heib 
Acked-by: Dumitru Ceara 
---
 ic/ovn-ic.c | 10 +++---
 tests/ovn-ic.at | 24 
 2 files changed, 31 insertions(+), 3 deletions(-)

diff --git a/ic/ovn-ic.c b/ic/ovn-ic.c
index 8ceb34d7c..12e2729ce 100644
--- a/ic/ovn-ic.c
+++ b/ic/ovn-ic.c
@@ -132,14 +132,18 @@ az_run(struct ic_context *ctx)
 return NULL;
 }
 
-/* Delete old AZ if name changes.  Note: if name changed when ovn-ic
- * is not running, one has to manually delete the old AZ with:
+/* Update old AZ if name changes.  Note: if name changed when ovn-ic
+ * is not running, one has to manually delete/update the old AZ with:
  * "ovn-ic-sbctl destroy avail ". */
 static char *az_name;
 const struct icsbrec_availability_zone *az;
 if (az_name && strcmp(az_name, nb_global->name)) {
 ICSBREC_AVAILABILITY_ZONE_FOR_EACH (az, ctx->ovnisb_idl) {
-if (!strcmp(az->name, az_name)) {
+/* AZ name update locally need to update az in ISB. */
+if (nb_global->name[0] && !strcmp(az->name, az_name)) {
+icsbrec_availability_zone_set_name(az, nb_global->name);
+break;
+} else if (!nb_global->name[0] && !strcmp(az->name, az_name)) {
 icsbrec_availability_zone_delete(az);
 break;
 }
diff --git a/tests/ovn-ic.at b/tests/ovn-ic.at
index d4c436f84..6061d054c 100644
--- a/tests/ovn-ic.at
+++ b/tests/ovn-ic.at
@@ -28,7 +28,31 @@ availability-zone az3
 ])
 
 OVN_CLEANUP_IC([az1], [az2])
+AT_CLEANUP
+])
+
+
+OVN_FOR_EACH_NORTHD([
+AT_SETUP([ovn-ic -- AZ update in GW])
+ovn_init_ic_db
+net_add n1
 
+ovn_start az1
+sim_add gw-az1
+as gw-az1
+
+check ovs-vsctl add-br br-phys
+ovn_az_attach az1 n1 br-phys 192.168.1.1
+check ovs-vsctl set open . external-ids:ovn-is-interconn=true
+
+az_uuid=$(fetch_column ic-sb:availability-zone _uuid name="az1")
+ovn_as az1 ovn-nbctl set NB_Global . name="az2"
+wait_column "$az_uuid" ic-sb:availability-zone _uuid name="az2"
+
+# make sure that gateway still point to the same AZ with new name
+wait_column "$az_uuid" ic-sb:gateway availability_zone name="gw-az1"
+
+OVN_CLEANUP_IC([az1])
 AT_CLEANUP
 ])
 
-- 
2.34.3

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


[ovs-dev] [PATCH ovn] Controller: Handle unconditional IDL messages while paused.

2024-01-23 Thread Mohammad Heib
If the user triggers a pause command to the ovn-controller the current
implementation will wait for commands from unixctl server only and
ignore the other component.

This implementation works fine if we don't have inactivity_probe set in
the SB DataBase, but once the user sets the inactivity_probe in SB
DataBase the connection will be dropped by the SBDB. Once the controller
resumes the execution it will try to commit some changes to the SBDB but
the transaction will fail since we lost the connection to the SBDB and
the controller must reconnect before committing the transaction again.

To avoid the above scenario the controller can keep handling
unconditional IDL messages to avoid reconnecting to SB.

Signed-off-by: Mohammad Heib 
---
 controller/ovn-controller.c | 16 +---
 ovn-sb.xml  |  2 +-
 tests/ovn-controller.at | 51 +
 3 files changed, 65 insertions(+), 4 deletions(-)

diff --git a/controller/ovn-controller.c b/controller/ovn-controller.c
index 856e5e270..d2c8f66d9 100644
--- a/controller/ovn-controller.c
+++ b/controller/ovn-controller.c
@@ -5534,12 +5534,22 @@ main(int argc, char *argv[])
 simap_destroy();
 }
 
-/* If we're paused just run the unixctl server and skip most of the
- * processing loop.
+/* If we're paused just run the unixctl-server/unconditional IDL and
+ *  skip most of the processing loop.
  */
 if (paused) {
 unixctl_server_run(unixctl);
+int ovnsb_seq = ovsdb_idl_get_seqno(ovnsb_idl_loop.idl);
+ovsdb_idl_run(ovnsb_idl_loop.idl);
+int new_ovnsb_seq = ovsdb_idl_get_seqno(ovnsb_idl_loop.idl);
+/* If the IDL content has changed while the controller is
+ * in pause state, trigger a recompute.
+ */
+if (new_ovnsb_seq != ovnsb_seq) {
+engine_set_force_recompute(true);
+}
 unixctl_server_wait(unixctl);
+ovsdb_idl_wait(ovnsb_idl_loop.idl);
 goto loop_done;
 }
 
@@ -6009,7 +6019,6 @@ main(int argc, char *argv[])
 OVS_NOT_REACHED();
 }
 
-ovsdb_idl_track_clear(ovnsb_idl_loop.idl);
 ovsdb_idl_track_clear(ovs_idl_loop.idl);
 
 lflow_cache_run(ctrl_engine_ctx.lflow_cache);
@@ -6017,6 +6026,7 @@ main(int argc, char *argv[])
 
 loop_done:
 memory_wait();
+ovsdb_idl_track_clear(ovnsb_idl_loop.idl);
 poll_block();
 if (should_service_stop()) {
 exit_args.exiting = true;
diff --git a/ovn-sb.xml b/ovn-sb.xml
index e393f92b3..43c13f23c 100644
--- a/ovn-sb.xml
+++ b/ovn-sb.xml
@@ -4308,7 +4308,7 @@ tcp.flags = RST;
   
 Maximum number of milliseconds of idle time on connection to the client
 before sending an inactivity probe message.  If Open vSwitch does not
-communicate with the client for the specified number of seconds, it
+communicate with the client for the specified number of milliseconds,it
 will send a probe.  If a response is not received for the same
 additional amount of time, Open vSwitch assumes the connection has been
 broken and attempts to reconnect.  Default is implementation-specific.
diff --git a/tests/ovn-controller.at b/tests/ovn-controller.at
index 9d2a37c72..04e4c52e7 100644
--- a/tests/ovn-controller.at
+++ b/tests/ovn-controller.at
@@ -352,6 +352,57 @@ OVS_APP_EXIT_AND_WAIT([ovsdb-server])
 AT_CLEANUP
 ])
 
+# Check that the connection to the Southbound database
+# is not dropped when probe-interval is set and the controller
+# is in pause state.
+OVN_FOR_EACH_NORTHD([
+AT_SETUP([ovn-controller - check sbdb connection while pause])
+AT_KEYWORDS([ovn])
+ovn_start
+
+net_add n1
+sim_add hv
+as hv
+ovs-vsctl add-br br-phys
+ovn_attach n1 br-phys 192.168.0.1
+
+ovs-vsctl -- add-port br-int hv1-vif1 -- \
+set interface hv1-vif1 external-ids:iface-id=sw0-p1 \
+options:tx_pcap=hv1/vif1-tx.pcap \
+options:rxq_pcap=hv1/vif1-rx.pcap \
+ofport-request=1
+
+ovs-vsctl set open . external_ids:ovn-remote-probe-interval=10
+ovn-sbctl set connection . inactivity_probe=1
+
+ovn-nbctl ls-add sw0
+check ovn-nbctl lsp-add sw0 sw0-p1
+check ovn-nbctl lsp-set-addresses sw0-p1 "50:54:00:00:00:03 10.0.0.3"
+check ovn-nbctl lsp-set-port-security sw0-p1 "50:54:00:00:00:03 10.0.0.3"
+ovn-nbctl --wait=hv sync
+
+sleep_controller hv
+# Trigger DB change to make SBDB connect to controller.
+check ovn-nbctl lsp-del sw0-p1
+
+# wait for 2 sec to give enough time to the SBDB to drop the connection
+# if there is no answer from the controller. The connection should not
+# be dropped since we keep handle the idl messages from SBDB even if we
+# in pause state.
+sleep 2
+wake_up_controller hv
+
+check ovn-nbctl lsp-add sw0 sw0-p1
+check ovn-nbctl lsp-set-addresses sw0-p1 "50:54:00:00:00:03 10.0.0.3"
+check ovn-nbctl ls

[ovs-dev] [PATCH ovn 2/2] OVN-SB: Exposes igmp group protocol version through IGMP table.

2024-01-22 Thread Mohammad Heib
Expose the igmp/mld group protocol version through the
IGMP_GROUP table in SBDB.

This patch can be used by ovn consumer for debuggability purposes, user
now can  match between the protocol version used in the OVN logical
switches and the uplink ports.

Rreported-at: https://bugzilla.redhat.com/show_bug.cgi?id=2160476
Signed-off-by: Mohammad Heib 
---
 NEWS  |  2 ++
 controller/ip-mcast.c |  8 
 controller/ip-mcast.h |  3 +++
 controller/pinctrl.c  | 19 ++-
 northd/ovn-northd.c   |  2 +-
 ovn-sb.ovsschema  |  5 +++--
 ovn-sb.xml|  4 
 tests/ovn.at  |  3 +++
 8 files changed, 42 insertions(+), 4 deletions(-)

diff --git a/NEWS b/NEWS
index 5f267b4c6..9075e7d80 100644
--- a/NEWS
+++ b/NEWS
@@ -14,6 +14,8 @@ Post v23.09.0
   - ovn-northd-ddlog has been removed.
   - A new LSP option "enable_router_port_acl" has been added to enable
 conntrack for the router port whose peer is l3dgw_port if set it true.
+  - IGMP_Group have a new "protocol" column that displays the the group
+protocol version.
 
 OVN v23.09.0 - 15 Sep 2023
 --
diff --git a/controller/ip-mcast.c b/controller/ip-mcast.c
index a870fb29e..83e41c81f 100644
--- a/controller/ip-mcast.c
+++ b/controller/ip-mcast.c
@@ -226,6 +226,14 @@ igmp_group_cleanup(struct ovsdb_idl_txn *ovnsb_idl_txn,
 return true;
 }
 
+
+void igmp_group_set_protocol(const struct sbrec_igmp_group *group,
+ mcast_group_proto protocol)
+{
+sbrec_igmp_group_set_protocol(group,
+  mcast_snooping_group_protocol_str(protocol));
+}
+
 static const struct sbrec_igmp_group *
 igmp_group_lookup_(struct ovsdb_idl_index *igmp_groups,
const char *addr_str,
diff --git a/controller/ip-mcast.h b/controller/ip-mcast.h
index 326f39db1..f0c34343f 100644
--- a/controller/ip-mcast.h
+++ b/controller/ip-mcast.h
@@ -63,4 +63,7 @@ void igmp_group_delete(const struct sbrec_igmp_group *g);
 bool igmp_group_cleanup(struct ovsdb_idl_txn *ovnsb_idl_txn,
 struct ovsdb_idl_index *igmp_groups);
 
+void igmp_group_set_protocol(const struct sbrec_igmp_group *group,
+ mcast_group_proto protocol);
+
 #endif /* controller/ip-mcast.h */
diff --git a/controller/pinctrl.c b/controller/pinctrl.c
index 77bf67e58..6379b7afb 100644
--- a/controller/pinctrl.c
+++ b/controller/pinctrl.c
@@ -180,6 +180,7 @@ struct pinctrl {
 bool mac_binding_can_timestamp;
 bool fdb_can_timestamp;
 bool dns_supports_ovn_owned;
+bool igmp_support_protocol;
 };
 
 static struct pinctrl pinctrl;
@@ -3586,11 +3587,21 @@ pinctrl_update(const struct ovsdb_idl *idl, const char 
*br_int_name)
 if (dns_supports_ovn_owned != pinctrl.dns_supports_ovn_owned) {
 pinctrl.dns_supports_ovn_owned = dns_supports_ovn_owned;
 
-/* Notify pinctrl_handler that fdb timestamp column
+/* Notify pinctrl_handler that dns ovn_owned column
* availability has changed. */
 notify_pinctrl_handler();
 }
 
+bool igmp_support_proto =
+sbrec_server_has_igmp_group_table_col_protocol(idl);
+if (igmp_support_proto != pinctrl.igmp_support_protocol) {
+pinctrl.igmp_support_protocol = igmp_support_proto;
+
+/* Notify pinctrl_handler that igmp protocol column
+ * availability has changed. */
+notify_pinctrl_handler();
+}
+
 ovs_mutex_unlock(_mutex);
 }
 
@@ -5400,6 +5411,12 @@ ip_mcast_sync(struct ovsdb_idl_txn *ovnsb_idl_txn,
local_dp->datapath, chassis);
 }
 
+/* Set Group protocol*/
+if (pinctrl.igmp_support_protocol) {
+igmp_group_set_protocol(sbrec_igmp,
+mc_group->protocol_version);
+}
+
 igmp_group_update_ports(sbrec_igmp, sbrec_datapath_binding_by_key,
 sbrec_port_binding_by_key, ip_ms->ms,
 mc_group);
diff --git a/northd/ovn-northd.c b/northd/ovn-northd.c
index f3868068d..700c9cf6e 100644
--- a/northd/ovn-northd.c
+++ b/northd/ovn-northd.c
@@ -120,7 +120,7 @@ static const char *rbac_svc_monitor_auth_update[] =
 static const char *rbac_igmp_group_auth[] =
 {""};
 static const char *rbac_igmp_group_update[] =
-{"address", "chassis", "datapath", "ports"};
+{"address", "protocol", "chassis", "datapath", "ports"};
 static const char *rbac_bfd_auth[] =
 {""};
 static const char *rbac_bfd_update[] =
diff --git a/ovn-sb.ovsschema b/ovn-sb.ovsschema
index 72e230b75..240d65f69 100644
--- a/ovn-sb.ovsschema
+++ b/ovn-sb.ovsschema
@@ -1,7 +1,7 @@
 {
 "name": "OVN_Southbound",
-"version": "20.30.0",

[ovs-dev] [PATCH ovn 1/2] ovs: Bump submodule to include igmp protocol version.

2024-01-22 Thread Mohammad Heib
Specifically the following commit:
  077d0bad0436 ("mcast-snooping: Store IGMP/MLD protocol version.")

Also fix a small compilation error due to prototype change.

Signed-off-by: Mohammad Heib 
---
 controller/pinctrl.c | 6 +-
 ovs  | 2 +-
 2 files changed, 6 insertions(+), 2 deletions(-)

diff --git a/controller/pinctrl.c b/controller/pinctrl.c
index 4992eab08..77bf67e58 100644
--- a/controller/pinctrl.c
+++ b/controller/pinctrl.c
@@ -5474,9 +5474,13 @@ pinctrl_ip_mcast_handle_igmp(struct rconn *swconn,
 switch (ntohs(ip_flow->tp_src)) {
 case IGMP_HOST_MEMBERSHIP_REPORT:
 case IGMPV2_HOST_MEMBERSHIP_REPORT:
+mcast_group_proto grp_proto =
+(ntohs(ip_flow->tp_src) == IGMP_HOST_MEMBERSHIP_REPORT)
+? MCAST_GROUP_IGMPV1
+: MCAST_GROUP_IGMPV2;
 group_change =
 mcast_snooping_add_group4(ip_ms->ms, ip4, IP_MCAST_VLAN,
-  port_key_data);
+  port_key_data, grp_proto);
 break;
 case IGMP_HOST_LEAVE_MESSAGE:
 group_change =
diff --git a/ovs b/ovs
index 4102674b3..b222593bc 16
--- a/ovs
+++ b/ovs
@@ -1 +1 @@
-Subproject commit 4102674b3ecadb0e20e512cc661cddbbc4b3d1f6
+Subproject commit b222593bc69b5d82849d18eb435564f5f93449d3
-- 
2.34.3

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


[ovs-dev] [PATCH ovn v4 3/4] OVN-IC: Make it possible for CMS to detect when the ISB is up-to-date.

2024-01-09 Thread Mohammad Heib
Until now, there has been no reliable for the CMS to detect when
changes made to the INB configuration have been passed through
to the ISB, This commit adds this feature to the system,
by adding sequence numbers to the INB and ISB and adding code
in ovn-ic-nbctl, ovn-ic to keep those sequence numbers up-to-date.

The biggest user-visible change from this commit is a new option
'--wait' and new command 'sync' to ovn-ic-nbctl.
With --wait=sb, ovn-ic-nbctl now waits for ovn-ics to update the ISB
database.

Signed-off-by: Mohammad Heib 
Acked-by: Mark Michelson 
---
 utilities/ovn-ic-nbctl.8.xml | 49 
 utilities/ovn-ic-nbctl.c | 86 +++-
 2 files changed, 133 insertions(+), 2 deletions(-)

diff --git a/utilities/ovn-ic-nbctl.8.xml b/utilities/ovn-ic-nbctl.8.xml
index 4a70994b8..5a1324d2d 100644
--- a/utilities/ovn-ic-nbctl.8.xml
+++ b/utilities/ovn-ic-nbctl.8.xml
@@ -123,9 +123,58 @@
   
 
 
+Synchronization Commands
+
+
+  sync
+  
+Ordinarily, --wait=sb only waits for changes by the
+current ovn-ic-nbctl invocation to take effect.
+This means that, if none of the commands supplied to
+ovn-ic-nbctl change the database, then the command does
+not wait at all.  With the sync command, however,
+ovn-ic-nbctl waits even for earlier changes to the
+database to propagate down to the southbound database, according to the
+argument of --wait.
+  
+
+
 Options
 
 
+  --no-wait | --wait=none
+  --wait=sb
+
+  
+
+  These options control whether and how ovn-ic-nbctl waits
+  for the OVN system to become up-to-date with changes made in an
+  ovn-ic-nbctl invocation.
+
+
+
+  By default, or if --no-wait or --wait=none,
+  ovn-ic-nbctl exits immediately after confirming that
+  changes have been committed to the Interconnect northbound database,
+  without waiting.
+
+
+
+  With --wait=sb, before ovn-ic-nbctl exits,
+  it waits for ovn-ics to bring the Interconnect
+  southbound database up-to-date with the Interconnect northbound
+  database updates.
+
+
+
+  Ordinarily, --wait=sb only waits for changes by the
+  current ovn-ic-nbctl invocation to take effect.
+  This means that, if none of the commands supplied to
+  ovn-ic-nbctl change the database, then the command
+  does not wait at all.
+  Use the sync command to override this behavior.
+
+  
 --db database
 
   The OVSDB database remote to contact.  If the OVN_IC_NB_DB
diff --git a/utilities/ovn-ic-nbctl.c b/utilities/ovn-ic-nbctl.c
index 721dc4586..4317c385a 100644
--- a/utilities/ovn-ic-nbctl.c
+++ b/utilities/ovn-ic-nbctl.c
@@ -58,6 +58,13 @@ static bool oneline;
 /* --dry-run: Do not commit any changes. */
 static bool dry_run;
 
+/* --wait=TYPE: Wait for configuration change to take effect? */
+static enum nbctl_wait_type wait_type = NBCTL_WAIT_NONE;
+
+/* Should we wait (if specified by 'wait_type') even if the commands don't
+ * change the database at all */
+static bool force_wait = false;
+
 /* --timeout: Time to wait for a connection to 'db'. */
 static unsigned int timeout;
 
@@ -161,6 +168,8 @@ parse_options(int argc, char *argv[], struct shash 
*local_options)
 OPT_DB = UCHAR_MAX + 1,
 OPT_ONELINE,
 OPT_NO_SYSLOG,
+OPT_NO_WAIT,
+OPT_WAIT,
 OPT_DRY_RUN,
 OPT_LOCAL,
 OPT_COMMANDS,
@@ -173,6 +182,8 @@ parse_options(int argc, char *argv[], struct shash 
*local_options)
 static const struct option global_long_options[] = {
 {"db", required_argument, NULL, OPT_DB},
 {"no-syslog", no_argument, NULL, OPT_NO_SYSLOG},
+{"no-wait", no_argument, NULL, OPT_NO_WAIT},
+{"wait", required_argument, NULL, OPT_WAIT},
 {"dry-run", no_argument, NULL, OPT_DRY_RUN},
 {"oneline", no_argument, NULL, OPT_ONELINE},
 {"timeout", required_argument, NULL, 't'},
@@ -234,7 +245,19 @@ parse_options(int argc, char *argv[], struct shash 
*local_options)
 case OPT_DRY_RUN:
 dry_run = true;
 break;
-
+case OPT_NO_WAIT:
+wait_type = NBCTL_WAIT_NONE;
+break;
+case OPT_WAIT:
+if (!strcmp(optarg, "none")) {
+wait_type = NBCTL_WAIT_NONE;
+} else if (!strcmp(optarg, "sb")) {
+wait_type = NBCTL_WAIT_SB;
+} else {
+ctl_fatal("argument to --wait must be "
+  "\"none\", \"sb\" ");
+}
+break;
 case OPT_LOCAL:
 if (shash_find(local_options, options

[ovs-dev] [PATCH ovn v4 4/4] ic/tests: add unit test for ic sync command

2024-01-09 Thread Mohammad Heib
add unit test that check validate that sync command
sync ISB properly

Signed-off-by: Mohammad Heib 
---
 tests/ovn-ic.at | 47 +++
 1 file changed, 47 insertions(+)

diff --git a/tests/ovn-ic.at b/tests/ovn-ic.at
index d4c436f84..f55ffa6cd 100644
--- a/tests/ovn-ic.at
+++ b/tests/ovn-ic.at
@@ -1274,3 +1274,50 @@ OVN_CLEANUP_IC([az1], [az2])
 
 AT_CLEANUP
 ])
+
+AT_SETUP([ovn-ic -- sync ISB status to INB])
+ovn_init_ic_db
+net_add n1
+
+ovn_start az1
+sim_add gw-az1
+as gw-az1
+
+check ovs-vsctl add-br br-phys
+ovn_az_attach az1 n1 br-phys 192.168.1.1
+check ovs-vsctl set open . external-ids:ovn-is-interconn=true
+as az1
+
+# pause ovn-ic instance
+check ovn-appctl -t ic/ovn-ic pause
+
+# run sync command in the background this commands
+# supposed to stuck since ovn-ic is paused.
+$(ovn-ic-nbctl --wait=sb sync &)
+
+for i in {1..5}; do
+set -- $(ovn-ic-nbctl get ic_nb_global . nb_ic_cfg sb_ic_cfg)
+AS_VAR_SET([ic_nb_cfg], [$1])
+AS_VAR_SET([ic_sb_cfg], [$2])
+if test $ic_nb_cfg -gt $ic_sb_cfg; then
+sleep 1
+else
+break
+fi
+done
+
+# if ic_nb_cfg equal to ic_sb_cfg that mean both zero
+# or both 1 which is a not correct and the test must fail.
+AT_FAIL_IF([test $ic_nb_cfg == $ic_sb_cfg])
+
+# resume ovn-ic instance
+check ovn-appctl -t ic/ovn-ic resume
+set -- $(ovn-ic-nbctl get ic_nb_global . nb_ic_cfg sb_ic_cfg)
+AS_VAR_SET([ic_nb_cfg], [$1])
+AS_VAR_SET([ic_sb_cfg], [$2])
+AT_FAIL_IF([test $ic_nb_cfg != 1])
+AT_FAIL_IF([test $ic_nb_cfg != 1])
+
+OVN_CLEANUP_IC([az1])
+AT_CLEANUP
+])
-- 
2.34.3

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


[ovs-dev] [PATCH ovn v4 2/4] ovn-ic: implement basic INB change handling status

2024-01-09 Thread Mohammad Heib
This patch implements a basic sequence number protocol
that can be used by CMS to determine if the changes
applied to INB are successfully propagated to ISB.

The implementation of this patch relies on OVN-ICs
instances to update the ISB by adding a per AZ a nb_ic_cfg
counter that will be updated by the OVN-IC once it is done
and commit all needed changes to the ISB, and according to this
AZ:nb_ic_cfg the ISB and INB will be updating about the status
of the changes.

Signed-off-by: Mohammad Heib 
---
 ic/ovn-ic.c | 96 ++---
 1 file changed, 91 insertions(+), 5 deletions(-)

diff --git a/ic/ovn-ic.c b/ic/ovn-ic.c
index 8ceb34d7c..ba393e910 100644
--- a/ic/ovn-ic.c
+++ b/ic/ovn-ic.c
@@ -1782,16 +1782,96 @@ route_run(struct ic_context *ctx,
 hmap_destroy(_lrs);
 }
 
+/*
+ * This function implements a sequence number protocol that can be used by
+ * the INB end user to verify that ISB is synced with all the changes that
+ * are done be the user/AZs-controllers:
+ *
+ * Since we have multiple IC instances running in different regions
+ * we can't rely on one of them to update the ISB and sync that update
+ * to INB since other ICs can make changes in parallel.
+ * So to have a sequence number protocol working properly we must
+ * make sure that all the IC instances are synced with the ISB first
+ * and then update the INB.
+ *
+ * To guarantee that all instances are synced with ISB first, each IC
+ * will do the following steps:
+ *
+ * 1. when local ovn-ic sees that INB:nb_ic_cfg has updated we will set
+ *the ic_sb_loop->next_cfg to match the INB:nb_ic_cfg and increment
+ *the value of AZ:nb_ic_cfg and wait until we get confirmation from
+ *the server.
+ *
+ * 2. once this IC instance changes for ISB are committed successfully
+ *(next loop), the value of cur_cfg will be updated to match
+ *the INB:nb_ic_cfg that indicate that our local instance is up to date
+ *and no more changes need to be done for ISB.
+ *
+ * 3. validate that the AZ:nb_ic_cfg to match the INB:nb_ic_cfg.
+ *
+ * 4. Go through all the AZs and check if all have the same value of
+ *AZ:nb_ic_cfg that means all the AZs are done with ISB changes and ISB are
+ *up to date with INB, so we can set the values of ISB:nb_ic_cfg to
+ *INB:nb_ic_cfg and INB:sb_ic_cfg to INB:nb_ic_cfg.
+ */
 static void
-ovn_db_run(struct ic_context *ctx)
+update_sequence_numbers(const struct icsbrec_availability_zone *az,
+struct ic_context *ctx,
+struct ovsdb_idl_loop *ic_sb_loop)
 {
-const struct icsbrec_availability_zone *az = az_run(ctx);
-VLOG_DBG("Availability zone: %s", az ? az->name : "not created yet.");
+bool azs_cfg_equals = true;
+if (!ctx->ovnisb_txn || !ctx->ovninb_txn) {
+return;
+}
 
-if (!az) {
+const struct icnbrec_ic_nb_global *ic_nb = icnbrec_ic_nb_global_first(
+   ctx->ovninb_idl);
+if (!ic_nb) {
+ic_nb = icnbrec_ic_nb_global_insert(ctx->ovninb_txn);
+}
+const struct icsbrec_ic_sb_global *ic_sb = icsbrec_ic_sb_global_first(
+   ctx->ovnisb_idl);
+if (!ic_sb) {
+ic_sb = icsbrec_ic_sb_global_insert(ctx->ovnisb_txn);
+}
+
+if ((ic_nb->nb_ic_cfg != ic_sb->nb_ic_cfg) &&
+  (ic_nb->nb_ic_cfg != az->nb_ic_cfg)) {
+/* Deal with potential overflows. */
+if (az->nb_ic_cfg == LLONG_MAX) {
+icsbrec_availability_zone_set_nb_ic_cfg(az, 0);
+}
+ic_sb_loop->next_cfg = ic_nb->nb_ic_cfg;
+ovsdb_idl_txn_increment(ctx->ovnisb_txn, >header_,
+   _availability_zone_col_nb_ic_cfg, true);
 return;
 }
 
+/* handle cases where accidentally AZ:ic_nb_cfg exceeds
+ * the INB:ic_nb_cfg.
+ */
+if (az->nb_ic_cfg != ic_sb_loop->cur_cfg) {
+icsbrec_availability_zone_set_nb_ic_cfg(az, ic_sb_loop->cur_cfg);
+return;
+}
+
+const struct icsbrec_availability_zone *other_az;
+ICSBREC_AVAILABILITY_ZONE_FOR_EACH (other_az, ctx->ovnisb_idl) {
+if (other_az->nb_ic_cfg != az->nb_ic_cfg) {
+azs_cfg_equals = false;
+}
+}
+
+if (azs_cfg_equals && (ic_nb->nb_ic_cfg != ic_sb->nb_ic_cfg)) {
+icsbrec_ic_sb_global_set_nb_ic_cfg(ic_sb, az->nb_ic_cfg);
+icnbrec_ic_nb_global_set_sb_ic_cfg(ic_nb, az->nb_ic_cfg);
+}
+}
+
+static void
+ovn_db_run(struct ic_context *ctx,
+   const struct icsbrec_availability_zone *az)
+{
 ts_run(ctx);
 gateway_run(ctx, az);
 port_binding_run(ctx, az);
@@ -2218,7 +2298,13 @@ main(int argc, char *argv[])
 ovsdb_idl_has_ever_connected(ctx.ovnsb_idl) &&
 ovsdb_idl_has_ever_connected(ctx.ovninb_i

[ovs-dev] [PATCH ovn v4 1/4] OVN-IC: interconnect DBs add basic Information Flow columns

2024-01-09 Thread Mohammad Heib
Add basic flow columns to interconnect northbound DB and
interconnect Southbound DB.

Those columns will be used by future patches to add basic
support for Information Flow in OVN  interconnect.

Signed-off-by: Mohammad Heib 
Acked-by: Mark Michelson 
Acked-by: Ales Musil 
---
 NEWS|  8 
 ovn-ic-nb.ovsschema |  6 --
 ovn-ic-nb.xml   | 17 +
 ovn-ic-sb.ovsschema |  8 +---
 ovn-ic-sb.xml   | 21 +
 5 files changed, 55 insertions(+), 5 deletions(-)

diff --git a/NEWS b/NEWS
index 20df92cb7..23609957c 100644
--- a/NEWS
+++ b/NEWS
@@ -12,6 +12,14 @@ Post v23.09.0
   - Support CIDR based MAC binding aging threshold. See ovn-nb(5) for
 'mac_binding_age_threshold' for more details.
   - ovn-northd-ddlog has been removed.
+  - OVN Interconnection:
+* INB provides basic feedback to the CMS about the ISB changes
+  handling status.
+* IC_NB_Global now have "nb_ic_cfg" and "sb_ic_cfg" columns for
+  for ISB informational status.
+* IC_SB_Global now have "nb_ic_cfg" column for ISB informational status.
+* Availability_Zone now have "nb_ic_cfg" column for local AZ
+  informational status.
 
 OVN v23.09.0 - 15 Sep 2023
 --
diff --git a/ovn-ic-nb.ovsschema b/ovn-ic-nb.ovsschema
index 894db8344..bee174357 100644
--- a/ovn-ic-nb.ovsschema
+++ b/ovn-ic-nb.ovsschema
@@ -1,10 +1,12 @@
 {
 "name": "OVN_IC_Northbound",
-"version": "1.0.0",
-"cksum": "45589876 3383",
+"version": "1.1.0",
+"cksum": "3964083684 3501",
 "tables": {
 "IC_NB_Global": {
 "columns": {
+"nb_ic_cfg": {"type": {"key": "integer"}},
+"sb_ic_cfg": {"type": {"key": "integer"}},
 "external_ids": {
 "type": {"key": "string", "value": "string",
  "min": 0, "max": "unlimited"}},
diff --git a/ovn-ic-nb.xml b/ovn-ic-nb.xml
index 8c53bec3b..2ae9bf6d5 100644
--- a/ovn-ic-nb.xml
+++ b/ovn-ic-nb.xml
@@ -36,6 +36,23 @@
   one row.
 
 
+
+  These columns allow a client to track the overall configuration state of
+  the system.
+
+  
+Sequence number for client to increment. When a client modifies the
+interconnect northbound database configuration and wishes to wait for
+OVN-ICs to handle this change and update the Interconnect
+southbound database, it may increment this sequence number.
+  
+  
+Sequence number that one OVN-IC sets to the value of
+ after waiting to all the OVN-ICs
+finish applying their changes to interconnect southbound database.
+  
+
+
 
   
 See External IDs at the beginning of this document.
diff --git a/ovn-ic-sb.ovsschema b/ovn-ic-sb.ovsschema
index 1d60b36d1..5baf141cf 100644
--- a/ovn-ic-sb.ovsschema
+++ b/ovn-ic-sb.ovsschema
@@ -1,10 +1,11 @@
 {
 "name": "OVN_IC_Southbound",
-"version": "1.1.1",
-"cksum": "3684563024 6914",
+"version": "1.2.0",
+"cksum": "1381014956 7032",
 "tables": {
 "IC_SB_Global": {
 "columns": {
+"nb_ic_cfg": {"type": {"key": "integer"}},
 "external_ids": {
 "type": {"key": "string", "value": "string",
  "min": 0, "max": "unlimited"}},
@@ -24,7 +25,8 @@
 "isRoot": true},
 "Availability_Zone": {
 "columns": {
-"name": {"type": "string"}},
+"name": {"type": "string"},
+"nb_ic_cfg": {"type": {"key": "integer"}}},
 "isRoot": true,
 "indexes": [["name"]]},
 "Gateway": {
diff --git a/ovn-ic-sb.xml b/ovn-ic-sb.xml
index f7e17e113..c3e7d2173 100644
--- a/ovn-ic-sb.xml
+++ b/ovn-ic-sb.xml
@@ -69,6 +69,21 @@
   one row.
 
 
+
+  This column allow a client to track the overall configuration state of
+  the system.
+
+  
+Sequence number for the configuration. When a CMS or
+ovn-ic-nbctl updates the Interconnect northbound database,
+it increments the nb_ic_cfg column in the
+NB_IC_Global table in the Interconnect northbound
+database. when OVN-ICs updates the southbound database to
+bring it up to date with these changes, one OVN-IC updates
+this column to the same value.
+  
+
+
 
   
 See External IDs at the beginning of this document.
@@ -102,6 +117,12 @@
 
   A name that uniquely identifies the availability zone.
 
+
+
+  This column is used by the OVN-IC to inform
+  that this IC instance is aligned with the changes in INB
+
+
   
 
   
-- 
2.34.3

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


[ovs-dev] [PATCH ovn v4 0/4] OVN-IC: add basic sequence number status support

2024-01-09 Thread Mohammad Heib
Currently, OVN-IC doesn't support a way to tell the end-user when their changes
to the IC-NB database have propagated successfully to the IC-SB Database.

This patch series adds basic support for the sequence number status protocol
that is implemented on the native OVN, with this patch series the end user
now can wait for their changes in the IC-NB DB to take effect by executing the
'sync' command after applying any changes to the IC-NB DB, for example, if the
end-user has created a transit switch in the IC-NB global DB and want to make
sure that the IC-SB create a DP binding for this ts-switch the user now can use
the 'sync' command as following:
$ ovn-ic-nbctl ts-add ts1
$ ovn-ic-nbctl --wait=sb sync

The second command will wait until all the ovn-ic instances see the new changes
and update their own local dbs and the global IC-SB db.

v3 -> v4

* Addressed review comments from Ales to add check for the 
  overflow cases.

v2 -> v3

* Rebase over main.
* Addressed review comments from Mark and Ales.


Mohammad Heib (4):
  OVN-IC: interconnect DBs add basic Information Flow columns
  ovn-ic: implement basic INB change handling status
  OVN-IC: Make it possible for CMS to detect when the ISB is up-to-date.
  ic/tests: add unit test for ic sync command

 NEWS |  8 +++
 ic/ovn-ic.c  | 96 ++--
 ovn-ic-nb.ovsschema  |  6 ++-
 ovn-ic-nb.xml| 17 +++
 ovn-ic-sb.ovsschema  |  8 +--
 ovn-ic-sb.xml| 21 
 tests/ovn-ic.at  | 47 ++
 utilities/ovn-ic-nbctl.8.xml | 49 ++
 utilities/ovn-ic-nbctl.c | 89 -
 9 files changed, 329 insertions(+), 12 deletions(-)

-- 
2.34.3

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


Re: [ovs-dev] [PATCH ovn v2 3/4] IC: Make it possible for CMS to detect when the ISB is up-to-date.

2024-01-09 Thread Mohammad Heib
Hi Ales,

Thank you for your review :)

i addressed most of your comments in v3, i just have one small comment
please see below:

On Tue, Jan 2, 2024 at 10:13 AM Ales Musil  wrote:

>
>
> On Wed, Dec 20, 2023 at 4:28 PM Mohammad Heib  wrote:
>
>> Until now, there has been no reliable for the CMS to detect when
>> changes made to the INB configuration have been passed through
>> to the ISB, This commit adds this feature to the system,
>> by adding sequence numbers to the INB and ISB and adding code
>> in ovn-ic-nbctl, ovn-ic to keep those sequence numbers up-to-date.
>>
>> The biggest user-visible change from this commit is a new option
>> '--wait' and new command 'sync' to ovn-ic-nbctl.
>> With --wait=sb, ovn-ic-nbctl now waits for ovn-ics to update the ISB
>> database.
>>
>> Signed-off-by: Mohammad Heib 
>>
> ---
>>
>
> Hi Mohammad,
>
> thank you for the series, I have a few comments down below. One small nit,
> the commit messages are a bit inconsistent, some patches have label IC,
> some ovn-ci. I guess all of this would fall into category ovn-ic with
> exception to the last patch. Also please include a cover letter for a
> series that has some common theme.
>
>
>>  utilities/ovn-ic-nbctl.8.xml | 49 +++
>>  utilities/ovn-ic-nbctl.c | 77 +++-
>>  2 files changed, 124 insertions(+), 2 deletions(-)
>>
>> diff --git a/utilities/ovn-ic-nbctl.8.xml b/utilities/ovn-ic-nbctl.8.xml
>> index 4a70994b8..5a1324d2d 100644
>> --- a/utilities/ovn-ic-nbctl.8.xml
>> +++ b/utilities/ovn-ic-nbctl.8.xml
>> @@ -123,9 +123,58 @@
>>
>>  
>>
>> +Synchronization Commands
>> +
>> +
>> +  sync
>> +  
>> +Ordinarily, --wait=sb only waits for changes by the
>> +current ovn-ic-nbctl invocation to take effect.
>> +This means that, if none of the commands supplied to
>> +ovn-ic-nbctl change the database, then the command
>> does
>> +not wait at all.  With the sync command, however,
>> +ovn-ic-nbctl waits even for earlier changes to the
>> +database to propagate down to the southbound database, according
>> to the
>> +argument of --wait.
>> +  
>> +
>> +
>>  Options
>>
>>  
>> +  --no-wait | --wait=none
>> +  --wait=sb
>> +
>> +  
>> +
>> +  These options control whether and how
>> ovn-ic-nbctl waits
>> +  for the OVN system to become up-to-date with changes made in an
>> +  ovn-ic-nbctl invocation.
>> +
>> +
>> +
>> +  By default, or if --no-wait or
>> --wait=none,
>> +  ovn-ic-nbctl exits immediately after confirming
>> that
>> +  changes have been committed to the Interconnect northbound
>> database,
>> +  without waiting.
>> +
>> +
>> +
>> +  With --wait=sb, before ovn-ic-nbctl
>> exits,
>> +  it waits for ovn-ics to bring the Interconnect
>> +  southbound database up-to-date with the Interconnect northbound
>> +  database updates.
>> +
>> +
>> +
>> +  Ordinarily, --wait=sb only waits for changes by
>> the
>> +  current ovn-ic-nbctl invocation to take effect.
>> +  This means that, if none of the commands supplied to
>> +  ovn-ic-nbctl change the database, then the command
>> +  does not wait at all.
>> +  Use the sync command to override this behavior.
>> +
>> +  
>>  --db database
>>  
>>The OVSDB database remote to contact.  If the
>> OVN_IC_NB_DB
>> diff --git a/utilities/ovn-ic-nbctl.c b/utilities/ovn-ic-nbctl.c
>> index 721dc4586..7eca5bdc4 100644
>> --- a/utilities/ovn-ic-nbctl.c
>> +++ b/utilities/ovn-ic-nbctl.c
>> @@ -58,6 +58,13 @@ static bool oneline;
>>  /* --dry-run: Do not commit any changes. */
>>  static bool dry_run;
>>
>> +/* --wait=TYPE: Wait for configuration change to take effect? */
>> +static enum nbctl_wait_type wait_type = NBCTL_WAIT_NONE;
>> +
>> +/* Should we wait (if specified by 'wait_type') even if the commands
>> don't
>> + * change the database at all */
>> +static bool force_wait = false;
>> +
>>  /* --timeout: Time to wait for a connection to 'db'. */
>>  static unsigned int timeout;
>>
>> @@ -161,6 +168,8 

[ovs-dev] [PATCH ovn v3 3/4] OVN-IC: Make it possible for CMS to detect when the ISB is up-to-date.

2024-01-09 Thread Mohammad Heib
Until now, there has been no reliable for the CMS to detect when
changes made to the INB configuration have been passed through
to the ISB, This commit adds this feature to the system,
by adding sequence numbers to the INB and ISB and adding code
in ovn-ic-nbctl, ovn-ic to keep those sequence numbers up-to-date.

The biggest user-visible change from this commit is a new option
'--wait' and new command 'sync' to ovn-ic-nbctl.
With --wait=sb, ovn-ic-nbctl now waits for ovn-ics to update the ISB
database.

Signed-off-by: Mohammad Heib 
Acked-by: Mark Michelson 
Signed-off-by: Mohammad Heib 
---
 utilities/ovn-ic-nbctl.8.xml | 49 +
 utilities/ovn-ic-nbctl.c | 85 +++-
 2 files changed, 132 insertions(+), 2 deletions(-)

diff --git a/utilities/ovn-ic-nbctl.8.xml b/utilities/ovn-ic-nbctl.8.xml
index 4a70994b8..5a1324d2d 100644
--- a/utilities/ovn-ic-nbctl.8.xml
+++ b/utilities/ovn-ic-nbctl.8.xml
@@ -123,9 +123,58 @@
   
 
 
+Synchronization Commands
+
+
+  sync
+  
+Ordinarily, --wait=sb only waits for changes by the
+current ovn-ic-nbctl invocation to take effect.
+This means that, if none of the commands supplied to
+ovn-ic-nbctl change the database, then the command does
+not wait at all.  With the sync command, however,
+ovn-ic-nbctl waits even for earlier changes to the
+database to propagate down to the southbound database, according to the
+argument of --wait.
+  
+
+
 Options
 
 
+  --no-wait | --wait=none
+  --wait=sb
+
+  
+
+  These options control whether and how ovn-ic-nbctl waits
+  for the OVN system to become up-to-date with changes made in an
+  ovn-ic-nbctl invocation.
+
+
+
+  By default, or if --no-wait or --wait=none,
+  ovn-ic-nbctl exits immediately after confirming that
+  changes have been committed to the Interconnect northbound database,
+  without waiting.
+
+
+
+  With --wait=sb, before ovn-ic-nbctl exits,
+  it waits for ovn-ics to bring the Interconnect
+  southbound database up-to-date with the Interconnect northbound
+  database updates.
+
+
+
+  Ordinarily, --wait=sb only waits for changes by the
+  current ovn-ic-nbctl invocation to take effect.
+  This means that, if none of the commands supplied to
+  ovn-ic-nbctl change the database, then the command
+  does not wait at all.
+  Use the sync command to override this behavior.
+
+  
 --db database
 
   The OVSDB database remote to contact.  If the OVN_IC_NB_DB
diff --git a/utilities/ovn-ic-nbctl.c b/utilities/ovn-ic-nbctl.c
index 721dc4586..81c1ea00f 100644
--- a/utilities/ovn-ic-nbctl.c
+++ b/utilities/ovn-ic-nbctl.c
@@ -58,6 +58,13 @@ static bool oneline;
 /* --dry-run: Do not commit any changes. */
 static bool dry_run;
 
+/* --wait=TYPE: Wait for configuration change to take effect? */
+static enum nbctl_wait_type wait_type = NBCTL_WAIT_NONE;
+
+/* Should we wait (if specified by 'wait_type') even if the commands don't
+ * change the database at all */
+static bool force_wait = false;
+
 /* --timeout: Time to wait for a connection to 'db'. */
 static unsigned int timeout;
 
@@ -161,6 +168,8 @@ parse_options(int argc, char *argv[], struct shash 
*local_options)
 OPT_DB = UCHAR_MAX + 1,
 OPT_ONELINE,
 OPT_NO_SYSLOG,
+OPT_NO_WAIT,
+OPT_WAIT,
 OPT_DRY_RUN,
 OPT_LOCAL,
 OPT_COMMANDS,
@@ -173,6 +182,8 @@ parse_options(int argc, char *argv[], struct shash 
*local_options)
 static const struct option global_long_options[] = {
 {"db", required_argument, NULL, OPT_DB},
 {"no-syslog", no_argument, NULL, OPT_NO_SYSLOG},
+{"no-wait", no_argument, NULL, OPT_NO_WAIT},
+{"wait", required_argument, NULL, OPT_WAIT},
 {"dry-run", no_argument, NULL, OPT_DRY_RUN},
 {"oneline", no_argument, NULL, OPT_ONELINE},
 {"timeout", required_argument, NULL, 't'},
@@ -234,7 +245,19 @@ parse_options(int argc, char *argv[], struct shash 
*local_options)
 case OPT_DRY_RUN:
 dry_run = true;
 break;
-
+case OPT_NO_WAIT:
+wait_type = NBCTL_WAIT_NONE;
+break;
+case OPT_WAIT:
+if (!strcmp(optarg, "none")) {
+wait_type = NBCTL_WAIT_NONE;
+} else if (!strcmp(optarg, "sb")) {
+wait_type = NBCTL_WAIT_SB;
+} else {
+ctl_fatal("argument to --wait must be "
+  "\"none\", \"sb\" ");
+}
+break;
 case OPT_LOCAL:
 if (sh

[ovs-dev] [PATCH ovn v3 1/4] OVN-IC: interconnect DBs add basic Information Flow columns

2024-01-09 Thread Mohammad Heib
Add basic flow columns to interconnect northbound DB and
interconnect Southbound DB.

Those columns will be used by future patches to add basic
support for Information Flow in OVN  interconnect.

Signed-off-by: Mohammad Heib 
Acked-by: Mark Michelson 
Acked-by: Ales Musil 
---
 NEWS|  8 
 ovn-ic-nb.ovsschema |  6 --
 ovn-ic-nb.xml   | 17 +
 ovn-ic-sb.ovsschema |  8 +---
 ovn-ic-sb.xml   | 21 +
 5 files changed, 55 insertions(+), 5 deletions(-)

diff --git a/NEWS b/NEWS
index 20df92cb7..23609957c 100644
--- a/NEWS
+++ b/NEWS
@@ -12,6 +12,14 @@ Post v23.09.0
   - Support CIDR based MAC binding aging threshold. See ovn-nb(5) for
 'mac_binding_age_threshold' for more details.
   - ovn-northd-ddlog has been removed.
+  - OVN Interconnection:
+* INB provides basic feedback to the CMS about the ISB changes
+  handling status.
+* IC_NB_Global now have "nb_ic_cfg" and "sb_ic_cfg" columns for
+  for ISB informational status.
+* IC_SB_Global now have "nb_ic_cfg" column for ISB informational status.
+* Availability_Zone now have "nb_ic_cfg" column for local AZ
+  informational status.
 
 OVN v23.09.0 - 15 Sep 2023
 --
diff --git a/ovn-ic-nb.ovsschema b/ovn-ic-nb.ovsschema
index 894db8344..bee174357 100644
--- a/ovn-ic-nb.ovsschema
+++ b/ovn-ic-nb.ovsschema
@@ -1,10 +1,12 @@
 {
 "name": "OVN_IC_Northbound",
-"version": "1.0.0",
-"cksum": "45589876 3383",
+"version": "1.1.0",
+"cksum": "3964083684 3501",
 "tables": {
 "IC_NB_Global": {
 "columns": {
+"nb_ic_cfg": {"type": {"key": "integer"}},
+"sb_ic_cfg": {"type": {"key": "integer"}},
 "external_ids": {
 "type": {"key": "string", "value": "string",
  "min": 0, "max": "unlimited"}},
diff --git a/ovn-ic-nb.xml b/ovn-ic-nb.xml
index 8c53bec3b..2ae9bf6d5 100644
--- a/ovn-ic-nb.xml
+++ b/ovn-ic-nb.xml
@@ -36,6 +36,23 @@
   one row.
 
 
+
+  These columns allow a client to track the overall configuration state of
+  the system.
+
+  
+Sequence number for client to increment. When a client modifies the
+interconnect northbound database configuration and wishes to wait for
+OVN-ICs to handle this change and update the Interconnect
+southbound database, it may increment this sequence number.
+  
+  
+Sequence number that one OVN-IC sets to the value of
+ after waiting to all the OVN-ICs
+finish applying their changes to interconnect southbound database.
+  
+
+
 
   
 See External IDs at the beginning of this document.
diff --git a/ovn-ic-sb.ovsschema b/ovn-ic-sb.ovsschema
index 1d60b36d1..5baf141cf 100644
--- a/ovn-ic-sb.ovsschema
+++ b/ovn-ic-sb.ovsschema
@@ -1,10 +1,11 @@
 {
 "name": "OVN_IC_Southbound",
-"version": "1.1.1",
-"cksum": "3684563024 6914",
+"version": "1.2.0",
+"cksum": "1381014956 7032",
 "tables": {
 "IC_SB_Global": {
 "columns": {
+"nb_ic_cfg": {"type": {"key": "integer"}},
 "external_ids": {
 "type": {"key": "string", "value": "string",
  "min": 0, "max": "unlimited"}},
@@ -24,7 +25,8 @@
 "isRoot": true},
 "Availability_Zone": {
 "columns": {
-"name": {"type": "string"}},
+"name": {"type": "string"},
+"nb_ic_cfg": {"type": {"key": "integer"}}},
 "isRoot": true,
 "indexes": [["name"]]},
 "Gateway": {
diff --git a/ovn-ic-sb.xml b/ovn-ic-sb.xml
index f7e17e113..c3e7d2173 100644
--- a/ovn-ic-sb.xml
+++ b/ovn-ic-sb.xml
@@ -69,6 +69,21 @@
   one row.
 
 
+
+  This column allow a client to track the overall configuration state of
+  the system.
+
+  
+Sequence number for the configuration. When a CMS or
+ovn-ic-nbctl updates the Interconnect northbound database,
+it increments the nb_ic_cfg column in the
+NB_IC_Global table in the Interconnect northbound
+database. when OVN-ICs updates the southbound database to
+bring it up to date with these changes, one OVN-IC updates
+this column to the same value.
+  
+
+
 
   
 See External IDs at the beginning of this document.
@@ -102,6 +117,12 @@
 
   A name that uniquely identifies the availability zone.
 
+
+
+  This column is used by the OVN-IC to inform
+  that this IC instance is aligned with the changes in INB
+
+
   
 
   
-- 
2.34.3

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


[ovs-dev] [PATCH ovn v3 2/4] ovn-ic: implement basic INB change handling status

2024-01-09 Thread Mohammad Heib
This patch implements a basic sequence number protocol
that can be used by CMS to determine if the changes
applied to INB are successfully propagated to ISB.

The implementation of this patch relies on OVN-ICs
instances to update the ISB by adding a per AZ a nb_ic_cfg
counter that will be updated by the OVN-IC once it is done
and commit all needed changes to the ISB, and according to this
AZ:nb_ic_cfg the ISB and INB will be updating about the status
of the changes.

Signed-off-by: Mohammad Heib 
---
 ic/ovn-ic.c | 96 ++---
 1 file changed, 91 insertions(+), 5 deletions(-)

diff --git a/ic/ovn-ic.c b/ic/ovn-ic.c
index 8ceb34d7c..ba393e910 100644
--- a/ic/ovn-ic.c
+++ b/ic/ovn-ic.c
@@ -1782,16 +1782,96 @@ route_run(struct ic_context *ctx,
 hmap_destroy(_lrs);
 }
 
+/*
+ * This function implements a sequence number protocol that can be used by
+ * the INB end user to verify that ISB is synced with all the changes that
+ * are done be the user/AZs-controllers:
+ *
+ * Since we have multiple IC instances running in different regions
+ * we can't rely on one of them to update the ISB and sync that update
+ * to INB since other ICs can make changes in parallel.
+ * So to have a sequence number protocol working properly we must
+ * make sure that all the IC instances are synced with the ISB first
+ * and then update the INB.
+ *
+ * To guarantee that all instances are synced with ISB first, each IC
+ * will do the following steps:
+ *
+ * 1. when local ovn-ic sees that INB:nb_ic_cfg has updated we will set
+ *the ic_sb_loop->next_cfg to match the INB:nb_ic_cfg and increment
+ *the value of AZ:nb_ic_cfg and wait until we get confirmation from
+ *the server.
+ *
+ * 2. once this IC instance changes for ISB are committed successfully
+ *(next loop), the value of cur_cfg will be updated to match
+ *the INB:nb_ic_cfg that indicate that our local instance is up to date
+ *and no more changes need to be done for ISB.
+ *
+ * 3. validate that the AZ:nb_ic_cfg to match the INB:nb_ic_cfg.
+ *
+ * 4. Go through all the AZs and check if all have the same value of
+ *AZ:nb_ic_cfg that means all the AZs are done with ISB changes and ISB are
+ *up to date with INB, so we can set the values of ISB:nb_ic_cfg to
+ *INB:nb_ic_cfg and INB:sb_ic_cfg to INB:nb_ic_cfg.
+ */
 static void
-ovn_db_run(struct ic_context *ctx)
+update_sequence_numbers(const struct icsbrec_availability_zone *az,
+struct ic_context *ctx,
+struct ovsdb_idl_loop *ic_sb_loop)
 {
-const struct icsbrec_availability_zone *az = az_run(ctx);
-VLOG_DBG("Availability zone: %s", az ? az->name : "not created yet.");
+bool azs_cfg_equals = true;
+if (!ctx->ovnisb_txn || !ctx->ovninb_txn) {
+return;
+}
 
-if (!az) {
+const struct icnbrec_ic_nb_global *ic_nb = icnbrec_ic_nb_global_first(
+   ctx->ovninb_idl);
+if (!ic_nb) {
+ic_nb = icnbrec_ic_nb_global_insert(ctx->ovninb_txn);
+}
+const struct icsbrec_ic_sb_global *ic_sb = icsbrec_ic_sb_global_first(
+   ctx->ovnisb_idl);
+if (!ic_sb) {
+ic_sb = icsbrec_ic_sb_global_insert(ctx->ovnisb_txn);
+}
+
+if ((ic_nb->nb_ic_cfg != ic_sb->nb_ic_cfg) &&
+  (ic_nb->nb_ic_cfg != az->nb_ic_cfg)) {
+/* Deal with potential overflows. */
+if (az->nb_ic_cfg == LLONG_MAX) {
+icsbrec_availability_zone_set_nb_ic_cfg(az, 0);
+}
+ic_sb_loop->next_cfg = ic_nb->nb_ic_cfg;
+ovsdb_idl_txn_increment(ctx->ovnisb_txn, >header_,
+   _availability_zone_col_nb_ic_cfg, true);
 return;
 }
 
+/* handle cases where accidentally AZ:ic_nb_cfg exceeds
+ * the INB:ic_nb_cfg.
+ */
+if (az->nb_ic_cfg != ic_sb_loop->cur_cfg) {
+icsbrec_availability_zone_set_nb_ic_cfg(az, ic_sb_loop->cur_cfg);
+return;
+}
+
+const struct icsbrec_availability_zone *other_az;
+ICSBREC_AVAILABILITY_ZONE_FOR_EACH (other_az, ctx->ovnisb_idl) {
+if (other_az->nb_ic_cfg != az->nb_ic_cfg) {
+azs_cfg_equals = false;
+}
+}
+
+if (azs_cfg_equals && (ic_nb->nb_ic_cfg != ic_sb->nb_ic_cfg)) {
+icsbrec_ic_sb_global_set_nb_ic_cfg(ic_sb, az->nb_ic_cfg);
+icnbrec_ic_nb_global_set_sb_ic_cfg(ic_nb, az->nb_ic_cfg);
+}
+}
+
+static void
+ovn_db_run(struct ic_context *ctx,
+   const struct icsbrec_availability_zone *az)
+{
 ts_run(ctx);
 gateway_run(ctx, az);
 port_binding_run(ctx, az);
@@ -2218,7 +2298,13 @@ main(int argc, char *argv[])
 ovsdb_idl_has_ever_connected(ctx.ovnsb_idl) &&
 ovsdb_idl_has_ever_connected(ctx.ovninb_i

[ovs-dev] [PATCH ovn v3 4/4] ic/tests: add unit test for ic sync command

2024-01-09 Thread Mohammad Heib
add unit test that check validate that sync command
sync ISB properly

Signed-off-by: Mohammad Heib 
---
 tests/ovn-ic.at | 47 +++
 1 file changed, 47 insertions(+)

diff --git a/tests/ovn-ic.at b/tests/ovn-ic.at
index d4c436f84..f55ffa6cd 100644
--- a/tests/ovn-ic.at
+++ b/tests/ovn-ic.at
@@ -1274,3 +1274,50 @@ OVN_CLEANUP_IC([az1], [az2])
 
 AT_CLEANUP
 ])
+
+AT_SETUP([ovn-ic -- sync ISB status to INB])
+ovn_init_ic_db
+net_add n1
+
+ovn_start az1
+sim_add gw-az1
+as gw-az1
+
+check ovs-vsctl add-br br-phys
+ovn_az_attach az1 n1 br-phys 192.168.1.1
+check ovs-vsctl set open . external-ids:ovn-is-interconn=true
+as az1
+
+# pause ovn-ic instance
+check ovn-appctl -t ic/ovn-ic pause
+
+# run sync command in the background this commands
+# supposed to stuck since ovn-ic is paused.
+$(ovn-ic-nbctl --wait=sb sync &)
+
+for i in {1..5}; do
+set -- $(ovn-ic-nbctl get ic_nb_global . nb_ic_cfg sb_ic_cfg)
+AS_VAR_SET([ic_nb_cfg], [$1])
+AS_VAR_SET([ic_sb_cfg], [$2])
+if test $ic_nb_cfg -gt $ic_sb_cfg; then
+sleep 1
+else
+break
+fi
+done
+
+# if ic_nb_cfg equal to ic_sb_cfg that mean both zero
+# or both 1 which is a not correct and the test must fail.
+AT_FAIL_IF([test $ic_nb_cfg == $ic_sb_cfg])
+
+# resume ovn-ic instance
+check ovn-appctl -t ic/ovn-ic resume
+set -- $(ovn-ic-nbctl get ic_nb_global . nb_ic_cfg sb_ic_cfg)
+AS_VAR_SET([ic_nb_cfg], [$1])
+AS_VAR_SET([ic_sb_cfg], [$2])
+AT_FAIL_IF([test $ic_nb_cfg != 1])
+AT_FAIL_IF([test $ic_nb_cfg != 1])
+
+OVN_CLEANUP_IC([az1])
+AT_CLEANUP
+])
-- 
2.34.3

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


[ovs-dev] [PATCH ovn v3 0/4] OVN-IC: add basic sequence number status support

2024-01-09 Thread Mohammad Heib
Currently, OVN-IC doesn't support a way to tell the end-user when their changes
to the IC-NB database have propagated successfully to the IC-SB Database.

This patch series adds basic support for the sequence number status protocol
that is implemented on the native OVN, with this patch series the end user
now can wait for their changes in the IC-NB DB to take effect by executing the
'sync' command after applying any changes to the IC-NB DB, for example, if the
end-user has created a transit switch in the IC-NB global DB and want to make
sure that the IC-SB create a DP binding for this ts-switch the user now can use
the 'sync' command as following:
$ ovn-ic-nbctl ts-add ts1
$ ovn-ic-nbctl --wait=sb sync

The second command will wait until all the ovn-ic instances see the new changes
and update their own local dbs and the global IC-SB db.

v2 -> v3

* Rebase over main.
* Addressed review comments from Mark and Ales.

Mohammad Heib (4):
  OVN-IC: interconnect DBs add basic Information Flow columns
  ovn-ic: implement basic INB change handling status
  OVN-IC: Make it possible for CMS to detect when the ISB is up-to-date.
  ic/tests: add unit test for ic sync command

 NEWS |  8 +++
 ic/ovn-ic.c  | 96 ++--
 ovn-ic-nb.ovsschema  |  6 ++-
 ovn-ic-nb.xml| 17 +++
 ovn-ic-sb.ovsschema  |  8 +--
 ovn-ic-sb.xml| 21 
 tests/ovn-ic.at  | 47 ++
 utilities/ovn-ic-nbctl.8.xml | 49 ++
 utilities/ovn-ic-nbctl.c | 85 ++-
 9 files changed, 325 insertions(+), 12 deletions(-)

-- 
2.34.3

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


Re: [ovs-dev] [PATCH v6 1/2] mcast-snooping: Store IGMP/MLD protocol version.

2024-01-04 Thread Mohammad Heib
Hi Simon,
Thank you for the review :)

On Thu, Jan 4, 2024 at 1:27 PM Simon Horman  wrote:

> On Wed, Dec 27, 2023 at 01:15:22PM +0200, Mohammad Heib wrote:
> > Store igmp/mld protocol version into the
> > mcast_group internally, the multicast snooping feature
> > is used by many OVS consumers and those consumers heavily rely
> > on the OVS implementation to manage/deal with mcast groups,
> > some of those consumers also need to deal/expose the mcast protocol
> > to the end user for debuggability purposes.
> >
> > OVN for example needs to expose the protocol version to the end user
> > to match between the protocol version used in the OVN logical switches
> > and the uplink ports
> >
> > Therefore, instead of implementing this in each OVS consumer that needs
> > to deal mcast group protocol version which will be very complicated
> > implementation since it rely on the OVS code, saving the protocol to
> > the mdb inside OVS will give that consumer access to the protocol version
> > very easily.
> >
> > Signed-off-by: Mohammad Heib 
> > ---
> > v6: Rebase on top of current master.
> > Address comments from Eelco:
> > - hardcode MCAST_GROUP_IGMPV3 inside mcast_snooping_add_report
> >   function.
> > ---
> >  lib/mcast-snooping.c | 20 ++--
> >  lib/mcast-snooping.h | 18 --
> >  ofproto/ofproto-dpif-xlate.c |  7 ++-
> >  3 files changed, 36 insertions(+), 9 deletions(-)
> >
> > diff --git a/lib/mcast-snooping.c b/lib/mcast-snooping.c
> > index 43805ae4d..995216a4b 100644
> > --- a/lib/mcast-snooping.c
> > +++ b/lib/mcast-snooping.c
> > @@ -389,7 +389,8 @@ mcast_snooping_prune_expired(struct mcast_snooping
> *ms,
> >  bool
> >  mcast_snooping_add_group(struct mcast_snooping *ms,
> >   const struct in6_addr *addr,
> > - uint16_t vlan, void *port)
> > + uint16_t vlan, void *port,
> > + mcast_group_proto grp_proto)
> >  OVS_REQ_WRLOCK(ms->rwlock)
> >  {
> >  bool learned;
> > @@ -424,6 +425,9 @@ mcast_snooping_add_group(struct mcast_snooping *ms,
> >  }
> >  mcast_group_insert_bundle(ms, grp, port, ms->idle_time);
>
> Hi Mohammad,
>
> the code leading up to this hunk looks a bit like this:
>
> grp = mcast_snooping_lookup(ms, addr, vlan);
> if (!grp) {
> /* Create grp */
> } else {
> ovs_list_remove(>group_node);
> }
> mcast_group_insert_bundle(ms, grp, port, ms->idle_time);
>
> In v4 of the patchset grp->protocol_version was set inside the
> (!grp) arm of the if condition. But now it is set below.
>
> Is this intentional? If so, I have a few questions:
>
yes, i updated the code to cover cases where a new port that uses a
different igmp/mld version will be added to this group.

>
> 1. Is it ok to set grp->protocol_version after the
>mcast_group_insert_bundle() call?
>

yes, That will update the group version to match the protocol version used
by the latest added port,
that will not have any effect because we only use the protocol version for
debuggability/user-inform and
not used in the code at all.

2. Is it ok to reset grp->protocol_version for an existing grp?
>

actually, in v5 I was setting the protocol version for newly created grps
only, but based on feedback on v5 for Eelco Chaudron
<https://patchwork.ozlabs.org/project/openvswitch/list/?submitter=70613>
[v5]
<https://patchwork.ozlabs.org/project/openvswitch/patch/20231130153821.855531-2-mh...@redhat.com/>
i updated the code to store the latest protocol used to join this group
which will be more accurate in the DB.

3. Are there situations where 2 will change the value of
>grp->protocol_version?
>
only if the user uses two different ports each one using a different
igmp/mld version to join the same
mcast group, this is an infrequent scenario but it will be better to use
the latest join port protocol version.

>
> >
> > +/* update the protocol version. */
> > +grp->protocol_version = grp_proto;
> > +
> >  /* Mark 'grp' as recently used. */
> >  ovs_list_push_back(>group_lru, >group_node);
> >  return learned;
>
> ...
>


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


[ovs-dev] [PATCH v6 2/2] mcast-snooping: Add group protocol to mdb/show output.

2023-12-27 Thread Mohammad Heib
Expose the mcast group protocol via the mdb/show
command output.

Signed-off-by: Mohammad Heib 
---
 lib/mcast-snooping.c|  24 
 lib/mcast-snooping.h|   1 +
 ofproto/ofproto-dpif.c  |   9 ++-
 tests/mcast-snooping.at | 130 
 tests/stp.at|   6 +-
 5 files changed, 139 insertions(+), 31 deletions(-)

diff --git a/lib/mcast-snooping.c b/lib/mcast-snooping.c
index 995216a4b..60ef8381e 100644
--- a/lib/mcast-snooping.c
+++ b/lib/mcast-snooping.c
@@ -57,6 +57,30 @@ mcast_snooping_flood_unreg(const struct mcast_snooping *ms)
 return ms->flood_unreg;
 }
 
+char *
+mcast_snooping_group_protocol_str(mcast_group_proto grp_proto)
+{
+switch (grp_proto) {
+case MCAST_GROUP_IGMPV1:
+return "IGMPv1";
+break;
+case MCAST_GROUP_IGMPV2:
+return "IGMPv2";
+break;
+case MCAST_GROUP_IGMPV3:
+return "IGMPv3";
+break;
+case MCAST_GROUP_MLDV1:
+return "MLDv1";
+break;
+case MCAST_GROUP_MLDV2:
+return "MLDv2";
+break;
+default:
+return "UNKNOWN";
+}
+}
+
 bool
 mcast_snooping_is_query(ovs_be16 igmp_type)
 {
diff --git a/lib/mcast-snooping.h b/lib/mcast-snooping.h
index 8cc8fb0fb..acd9fdb68 100644
--- a/lib/mcast-snooping.h
+++ b/lib/mcast-snooping.h
@@ -224,6 +224,7 @@ bool mcast_snooping_add_mrouter(struct mcast_snooping *ms, 
uint16_t vlan,
 OVS_REQ_WRLOCK(ms->rwlock);
 bool mcast_snooping_is_query(ovs_be16 igmp_type);
 bool mcast_snooping_is_membership(ovs_be16 igmp_type);
+char * mcast_snooping_group_protocol_str(mcast_group_proto grp_proto);
 
 /* Flush. */
 void mcast_snooping_mdb_flush(struct mcast_snooping *ms);
diff --git a/ofproto/ofproto-dpif.c b/ofproto/ofproto-dpif.c
index 6e62ed1f9..434ea1670 100644
--- a/ofproto/ofproto-dpif.c
+++ b/ofproto/ofproto-dpif.c
@@ -6172,7 +6172,7 @@ ofproto_unixctl_mcast_snooping_show(struct unixctl_conn 
*conn,
 return;
 }
 
-ds_put_cstr(, " port  VLAN  GROUPAge\n");
+ds_put_cstr(, " port  VLAN  protocol  GROUPAge\n");
 ovs_rwlock_rdlock(>ms->rwlock);
 LIST_FOR_EACH (grp, group_node, >ms->group_lru) {
 LIST_FOR_EACH(b, bundle_node, >bundle_lru) {
@@ -6181,7 +6181,9 @@ ofproto_unixctl_mcast_snooping_show(struct unixctl_conn 
*conn,
 bundle = b->port;
 ofputil_port_to_string(ofbundle_get_a_port(bundle)->up.ofp_port,
NULL, name, sizeof name);
-ds_put_format(, "%5s  %4d  ", name, grp->vlan);
+ds_put_format(, "%5s  %4d  %8s  ", name, grp->vlan,
+  mcast_snooping_group_protocol_str(
+  grp->protocol_version));
 ipv6_format_mapped(>addr, );
 ds_put_format(, " %3d\n",
   mcast_bundle_age(ofproto->ms, b));
@@ -6195,8 +6197,9 @@ ofproto_unixctl_mcast_snooping_show(struct unixctl_conn 
*conn,
 bundle = mrouter->port;
 ofputil_port_to_string(ofbundle_get_a_port(bundle)->up.ofp_port,
NULL, name, sizeof name);
-ds_put_format(, "%5s  %4d  querier %3d\n",
+ds_put_format(, "%5s  %4d  %8s  querier %3d\n",
   name, mrouter->vlan,
+  mcast_snooping_group_protocol_str(-1),
   mcast_mrouter_age(ofproto->ms, mrouter));
 }
 ovs_rwlock_unlock(>ms->rwlock);
diff --git a/tests/mcast-snooping.at b/tests/mcast-snooping.at
index 890e6aca0..800a77504 100644
--- a/tests/mcast-snooping.at
+++ b/tests/mcast-snooping.at
@@ -44,9 +44,9 @@ AT_CHECK([ovs-appctl netdev-dummy/receive p2 \
 
'01005e015c8a38552552810006c0080046c0002401027c00ac111c01e00194041164ec1e027d'])
 
 AT_CHECK([ovs-appctl mdb/show br0], [0], [dnl
- port  VLAN  GROUPAge
-2  1725  querier   0
-2  1728  querier   0
+ port  VLAN  protocol  GROUPAge
+2  1725   UNKNOWN  querier   0
+2  1728   UNKNOWN  querier   0
 ])
 
 AT_CHECK([ovs-vsctl set Interface p2 options:tx_pcap=p2.pcap])
@@ -75,7 +75,7 @@ AT_CHECK([ovs-appctl netdev-dummy/receive p2 \
 
'01005e015c8a38552552810006bd080046c0002401027f00ac111901e00194041164ec10027d'])
 
 AT_CHECK([ovs-appctl mdb/show br0], [0], [dnl
- port  VLAN  GROUPAge
+ port  VLAN  protocol  GROUPAge
 ])
 
 
@@ -87,8 +87,8 @@ AT_CHECK([ovs-appctl netdev-dummy/receive p2 \
 
'ff0e4c67000c290e4c6786dd6021ff020001ff0e4c673a00050201008300e7b8ff02000

[ovs-dev] [PATCH v6 1/2] mcast-snooping: Store IGMP/MLD protocol version.

2023-12-27 Thread Mohammad Heib
Store igmp/mld protocol version into the
mcast_group internally, the multicast snooping feature
is used by many OVS consumers and those consumers heavily rely
on the OVS implementation to manage/deal with mcast groups,
some of those consumers also need to deal/expose the mcast protocol
to the end user for debuggability purposes.

OVN for example needs to expose the protocol version to the end user
to match between the protocol version used in the OVN logical switches
and the uplink ports

Therefore, instead of implementing this in each OVS consumer that needs
to deal mcast group protocol version which will be very complicated
implementation since it rely on the OVS code, saving the protocol to
the mdb inside OVS will give that consumer access to the protocol version
very easily.

Signed-off-by: Mohammad Heib 
---
v6: Rebase on top of current master.
Address comments from Eelco:
- hardcode MCAST_GROUP_IGMPV3 inside mcast_snooping_add_report
  function.
---
 lib/mcast-snooping.c | 20 ++--
 lib/mcast-snooping.h | 18 --
 ofproto/ofproto-dpif-xlate.c |  7 ++-
 3 files changed, 36 insertions(+), 9 deletions(-)

diff --git a/lib/mcast-snooping.c b/lib/mcast-snooping.c
index 43805ae4d..995216a4b 100644
--- a/lib/mcast-snooping.c
+++ b/lib/mcast-snooping.c
@@ -389,7 +389,8 @@ mcast_snooping_prune_expired(struct mcast_snooping *ms,
 bool
 mcast_snooping_add_group(struct mcast_snooping *ms,
  const struct in6_addr *addr,
- uint16_t vlan, void *port)
+ uint16_t vlan, void *port,
+ mcast_group_proto grp_proto)
 OVS_REQ_WRLOCK(ms->rwlock)
 {
 bool learned;
@@ -424,6 +425,9 @@ mcast_snooping_add_group(struct mcast_snooping *ms,
 }
 mcast_group_insert_bundle(ms, grp, port, ms->idle_time);
 
+/* update the protocol version. */
+grp->protocol_version = grp_proto;
+
 /* Mark 'grp' as recently used. */
 ovs_list_push_back(>group_lru, >group_node);
 return learned;
@@ -431,11 +435,12 @@ mcast_snooping_add_group(struct mcast_snooping *ms,
 
 bool
 mcast_snooping_add_group4(struct mcast_snooping *ms, ovs_be32 ip4,
- uint16_t vlan, void *port)
+ uint16_t vlan, void *port,
+ mcast_group_proto grp_proto)
 OVS_REQ_WRLOCK(ms->rwlock)
 {
 struct in6_addr addr = in6_addr_mapped_ipv4(ip4);
-return mcast_snooping_add_group(ms, , vlan, port);
+return mcast_snooping_add_group(ms, , vlan, port, grp_proto);
 }
 
 int
@@ -478,7 +483,8 @@ mcast_snooping_add_report(struct mcast_snooping *ms,
 || record->type == IGMPV3_CHANGE_TO_INCLUDE_MODE)) {
 ret = mcast_snooping_leave_group4(ms, ip4, vlan, port);
 } else {
-ret = mcast_snooping_add_group4(ms, ip4, vlan, port);
+ret = mcast_snooping_add_group4(ms, ip4, vlan, port,
+MCAST_GROUP_IGMPV3);
 }
 if (ret) {
 count++;
@@ -513,7 +519,8 @@ mcast_snooping_add_mld(struct mcast_snooping *ms,
 
 switch (mld->type) {
 case MLD_REPORT:
-ret = mcast_snooping_add_group(ms, addr, vlan, port);
+ret = mcast_snooping_add_group(ms, addr, vlan, port,
+   MCAST_GROUP_MLDV1);
 if (ret) {
 count++;
 }
@@ -545,7 +552,8 @@ mcast_snooping_add_mld(struct mcast_snooping *ms,
 || record->type == IGMPV3_CHANGE_TO_INCLUDE_MODE)) {
 ret = mcast_snooping_leave_group(ms, addr, vlan, port);
 } else {
-ret = mcast_snooping_add_group(ms, addr, vlan, port);
+ret = mcast_snooping_add_group(ms, addr, vlan, port,
+   MCAST_GROUP_MLDV2);
 }
 if (ret) {
 count++;
diff --git a/lib/mcast-snooping.h b/lib/mcast-snooping.h
index f120405da..8cc8fb0fb 100644
--- a/lib/mcast-snooping.h
+++ b/lib/mcast-snooping.h
@@ -39,6 +39,15 @@ struct mcast_snooping;
 /* Time, in seconds, before expiring a mrouter_port due to inactivity. */
 #define MCAST_MROUTER_PORT_IDLE_TIME 180
 
+/* Multicast group protocol. */
+typedef enum {
+MCAST_GROUP_IGMPV1 = 0,
+MCAST_GROUP_IGMPV2,
+MCAST_GROUP_IGMPV3,
+MCAST_GROUP_MLDV1,
+MCAST_GROUP_MLDV2,
+} mcast_group_proto;
+
 /* Multicast group entry.
  * Guarded by owning 'mcast_snooping''s rwlock. */
 struct mcast_group {
@@ -51,6 +60,9 @@ struct mcast_group {
 /* VLAN tag. */
 uint16_t vlan;
 
+/* Multicast group IPv6/IPv4 Protocol version IGMPv1,2,3 or MLDv1,2 */
+mcast_group_proto protocol_version;
+
 /* Node in parent struct mcast_snooping group_lru. */
 struct ovs_list group_node OVS_GUARDED;
 
@@ -185,10 +197,12 @@ mcast_snooping_lookup4(const struct mc

[ovs-dev] [PATCH ovn v2 4/4] ic/tests: add unit test for ic sync command

2023-12-20 Thread Mohammad Heib
add unit test that check validate that sync command
sync ISB properly

Signed-off-by: Mohammad Heib 
---
 tests/ovn-ic.at | 22 ++
 1 file changed, 22 insertions(+)

diff --git a/tests/ovn-ic.at b/tests/ovn-ic.at
index d4c436f84..da7c37817 100644
--- a/tests/ovn-ic.at
+++ b/tests/ovn-ic.at
@@ -1274,3 +1274,25 @@ OVN_CLEANUP_IC([az1], [az2])
 
 AT_CLEANUP
 ])
+
+AT_SETUP([ovn-ic -- sync ISB status to INB])
+ovn_init_ic_db
+net_add n1
+
+ovn_start az1
+sim_add gw-az1
+as gw-az1
+
+check ovs-vsctl add-br br-phys
+ovn_az_attach az1 n1 br-phys 192.168.1.1
+check ovs-vsctl set open . external-ids:ovn-is-interconn=true
+
+ovn-ic-nbctl --wait=sb sync
+set -- $(ovn-ic-nbctl get ic_nb_global . nb_ic_cfg sb_ic_cfg)
+AS_VAR_SET([ic_nb_cfg], [$1])
+AS_VAR_SET([ic_sb_cfg], [$2])
+check test $ic_nb_cfg == $ic_sb_cfg
+
+OVN_CLEANUP_IC([az1])
+AT_CLEANUP
+])
-- 
2.34.3

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


[ovs-dev] [PATCH ovn v2 3/4] IC: Make it possible for CMS to detect when the ISB is up-to-date.

2023-12-20 Thread Mohammad Heib
Until now, there has been no reliable for the CMS to detect when
changes made to the INB configuration have been passed through
to the ISB, This commit adds this feature to the system,
by adding sequence numbers to the INB and ISB and adding code
in ovn-ic-nbctl, ovn-ic to keep those sequence numbers up-to-date.

The biggest user-visible change from this commit is a new option
'--wait' and new command 'sync' to ovn-ic-nbctl.
With --wait=sb, ovn-ic-nbctl now waits for ovn-ics to update the ISB
database.

Signed-off-by: Mohammad Heib 
---
 utilities/ovn-ic-nbctl.8.xml | 49 +++
 utilities/ovn-ic-nbctl.c | 77 +++-
 2 files changed, 124 insertions(+), 2 deletions(-)

diff --git a/utilities/ovn-ic-nbctl.8.xml b/utilities/ovn-ic-nbctl.8.xml
index 4a70994b8..5a1324d2d 100644
--- a/utilities/ovn-ic-nbctl.8.xml
+++ b/utilities/ovn-ic-nbctl.8.xml
@@ -123,9 +123,58 @@
   
 
 
+Synchronization Commands
+
+
+  sync
+  
+Ordinarily, --wait=sb only waits for changes by the
+current ovn-ic-nbctl invocation to take effect.
+This means that, if none of the commands supplied to
+ovn-ic-nbctl change the database, then the command does
+not wait at all.  With the sync command, however,
+ovn-ic-nbctl waits even for earlier changes to the
+database to propagate down to the southbound database, according to the
+argument of --wait.
+  
+
+
 Options
 
 
+  --no-wait | --wait=none
+  --wait=sb
+
+  
+
+  These options control whether and how ovn-ic-nbctl waits
+  for the OVN system to become up-to-date with changes made in an
+  ovn-ic-nbctl invocation.
+
+
+
+  By default, or if --no-wait or --wait=none,
+  ovn-ic-nbctl exits immediately after confirming that
+  changes have been committed to the Interconnect northbound database,
+  without waiting.
+
+
+
+  With --wait=sb, before ovn-ic-nbctl exits,
+  it waits for ovn-ics to bring the Interconnect
+  southbound database up-to-date with the Interconnect northbound
+  database updates.
+
+
+
+  Ordinarily, --wait=sb only waits for changes by the
+  current ovn-ic-nbctl invocation to take effect.
+  This means that, if none of the commands supplied to
+  ovn-ic-nbctl change the database, then the command
+  does not wait at all.
+  Use the sync command to override this behavior.
+
+  
 --db database
 
   The OVSDB database remote to contact.  If the OVN_IC_NB_DB
diff --git a/utilities/ovn-ic-nbctl.c b/utilities/ovn-ic-nbctl.c
index 721dc4586..7eca5bdc4 100644
--- a/utilities/ovn-ic-nbctl.c
+++ b/utilities/ovn-ic-nbctl.c
@@ -58,6 +58,13 @@ static bool oneline;
 /* --dry-run: Do not commit any changes. */
 static bool dry_run;
 
+/* --wait=TYPE: Wait for configuration change to take effect? */
+static enum nbctl_wait_type wait_type = NBCTL_WAIT_NONE;
+
+/* Should we wait (if specified by 'wait_type') even if the commands don't
+ * change the database at all */
+static bool force_wait = false;
+
 /* --timeout: Time to wait for a connection to 'db'. */
 static unsigned int timeout;
 
@@ -161,6 +168,8 @@ parse_options(int argc, char *argv[], struct shash 
*local_options)
 OPT_DB = UCHAR_MAX + 1,
 OPT_ONELINE,
 OPT_NO_SYSLOG,
+OPT_NO_WAIT,
+OPT_WAIT,
 OPT_DRY_RUN,
 OPT_LOCAL,
 OPT_COMMANDS,
@@ -173,6 +182,8 @@ parse_options(int argc, char *argv[], struct shash 
*local_options)
 static const struct option global_long_options[] = {
 {"db", required_argument, NULL, OPT_DB},
 {"no-syslog", no_argument, NULL, OPT_NO_SYSLOG},
+{"no-wait", no_argument, NULL, OPT_NO_WAIT},
+{"wait", required_argument, NULL, OPT_WAIT},
 {"dry-run", no_argument, NULL, OPT_DRY_RUN},
 {"oneline", no_argument, NULL, OPT_ONELINE},
 {"timeout", required_argument, NULL, 't'},
@@ -234,7 +245,19 @@ parse_options(int argc, char *argv[], struct shash 
*local_options)
 case OPT_DRY_RUN:
 dry_run = true;
 break;
-
+case OPT_NO_WAIT:
+wait_type = NBCTL_WAIT_NONE;
+break;
+case OPT_WAIT:
+if (!strcmp(optarg, "none")) {
+wait_type = NBCTL_WAIT_NONE;
+} else if (!strcmp(optarg, "sb")) {
+wait_type = NBCTL_WAIT_SB;
+} else {
+ctl_fatal("argument to --wait must be "
+  "\"none\", \"sb\" ");
+}
+break;
 case OPT_LOCAL:
 if (shash_find(local_options, options[idx].name)) {

[ovs-dev] [PATCH ovn v2 2/4] ovn-ic: implement basic INB change handling status

2023-12-20 Thread Mohammad Heib
This patch implements a basic sequence number protocol
that can be used by CMS to determine if the changes
applied to INB are successfully propagated to ISB.

The implementation of this patch relies on OVN-ICs
instances to update the ISB by adding a per AZ a nb_ic_cfg
counter that will be updated by the OVN-IC once it is done
and commit all needed changes to the ISB, and according to this
AZ:nb_ic_cfg the ISB and INB will be updating about the status
of the changes.

Signed-off-by: Mohammad Heib 
---
 ic/ovn-ic.c | 98 +
 1 file changed, 92 insertions(+), 6 deletions(-)

diff --git a/ic/ovn-ic.c b/ic/ovn-ic.c
index 8ceb34d7c..b6a813432 100644
--- a/ic/ovn-ic.c
+++ b/ic/ovn-ic.c
@@ -1782,16 +1782,96 @@ route_run(struct ic_context *ctx,
 hmap_destroy(_lrs);
 }
 
+/*
+ * This function implements a sequence number protocol that can be used by
+ * the INB end user to verify that ISB is synced with all the changes that
+ * are done be the user/AZs-controllers:
+ *
+ * Since we have multiple IC instances running in different regions
+ * we can't rely on one of them to update the ISB and sync that update
+ * to INB since other ICs can make changes in parallel.
+ * So to have a sequence number protocol working properly we must
+ * make sure that all the IC instances are synced with the ISB first
+ * and then update the INB.
+ *
+ * To guarantee that all instances are synced with ISB first, each IC
+ * will do the following steps:
+ *
+ * 1. when local ovn-ic sees that INB:nb_ic_cfg has updated we will set
+ *the ic_sb_loop->next_cfg to match the INB:nb_ic_cfg and increment
+ *the value of AZ:nb_ic_cfg and wait until we get confirmation from
+ *the server.
+ *
+ * 2. once this IC instance changes for ISB are committed successfully
+ *(next loop), the value of cur_cfg will be updated to match
+ *the INB:nb_ic_cfg that indicate that our local instance is up to date
+ *and no more changes need to be done for ISB.
+ *
+ * 3. validate that the AZ:nb_ic_cfg to match the INB:nb_ic_cfg.
+ *
+ * 4. Go through all the AZs and check if all have the same value of
+ *AZ:nb_ic_cfg that means all the AZs are done with ISB changes and ISB are
+ *up to date with INB, so we can set the values of ISB:nb_ic_cfg to
+ *INB:nb_ic_cfg and INB:sb_ic_cfg to INB:nb_ic_cfg.
+ */
 static void
-ovn_db_run(struct ic_context *ctx)
+update_sequence_numbers(const struct icsbrec_availability_zone *az,
+struct ic_context *ctx,
+struct ovsdb_idl_loop *ic_sb_loop)
 {
-const struct icsbrec_availability_zone *az = az_run(ctx);
-VLOG_DBG("Availability zone: %s", az ? az->name : "not created yet.");
+bool azs_cfg_equals = true;
 
-if (!az) {
-return;
+if (ctx->ovnisb_txn && ctx->ovninb_txn) {
+const struct icnbrec_ic_nb_global *ic_nb = icnbrec_ic_nb_global_first(
+   ctx->ovninb_idl);
+if (!ic_nb) {
+ic_nb = icnbrec_ic_nb_global_insert(ctx->ovninb_txn);
+}
+const struct icsbrec_ic_sb_global *ic_sb = icsbrec_ic_sb_global_first(
+   ctx->ovnisb_idl);
+if (!ic_sb) {
+ic_sb = icsbrec_ic_sb_global_insert(ctx->ovnisb_txn);
+}
+
+if ((ic_nb->nb_ic_cfg != ic_sb->nb_ic_cfg) &&
+  (ic_nb->nb_ic_cfg != az->nb_ic_cfg)) {
+/* Deal with potential overflows. */
+if (az->nb_ic_cfg == LLONG_MAX) {
+icsbrec_availability_zone_set_nb_ic_cfg(az, 0);
+}
+ic_sb_loop->next_cfg = ic_nb->nb_ic_cfg;
+ovsdb_idl_txn_increment(ctx->ovnisb_txn, >header_,
+   _availability_zone_col_nb_ic_cfg, true);
+goto done;
+}
+
+/* handle cases where accidentally AZ:ic_nb_cfg exceeds
+ * the INB:ic_nb_cfg.
+ */
+if (az->nb_ic_cfg != ic_sb_loop->cur_cfg) {
+icsbrec_availability_zone_set_nb_ic_cfg(az, ic_sb_loop->cur_cfg);
+goto done;
+}
+
+const struct icsbrec_availability_zone *other_az;
+ICSBREC_AVAILABILITY_ZONE_FOR_EACH (other_az, ctx->ovnisb_idl) {
+if (other_az->nb_ic_cfg != az->nb_ic_cfg) {
+azs_cfg_equals = false;
+}
+}
+
+if (azs_cfg_equals && (ic_nb->nb_ic_cfg != ic_sb->nb_ic_cfg)) {
+icsbrec_ic_sb_global_set_nb_ic_cfg(ic_sb, az->nb_ic_cfg);
+icnbrec_ic_nb_global_set_sb_ic_cfg(ic_nb, az->nb_ic_cfg);
+}
 }
+done: ;
+}
 
+static void
+ovn_db_run(struct ic_context *ctx,
+   const struct icsbrec_availability_zone *az)
+{
 ts_run(ctx);
 gateway_run(ctx, az);
 port_binding_

[ovs-dev] [PATCH ovn v2 1/4] IC: interconnect DBs add basic Information Flow columns

2023-12-20 Thread Mohammad Heib
Add basic flow columns to interconnect northbound DB and
interconnect Southbound DB.

Those columns will be used by future patches to add basic
support for Information Flow in OVN  interconnect.

Signed-off-by: Mohammad Heib 
---
v3: rebase over main.
---
 NEWS|  8 
 ovn-ic-nb.ovsschema |  6 --
 ovn-ic-nb.xml   | 17 +
 ovn-ic-sb.ovsschema |  8 +---
 ovn-ic-sb.xml   | 21 +
 5 files changed, 55 insertions(+), 5 deletions(-)

diff --git a/NEWS b/NEWS
index e10fb79dd..0be3b07cc 100644
--- a/NEWS
+++ b/NEWS
@@ -9,6 +9,14 @@ Post v23.09.0
 connection method and doesn't require additional probing.
 external_ids:ovn-openflow-probe-interval configuration option for
 ovn-controller no longer matters and is ignored.
+  - OVN Interconnection:
+* INB provides basic feedback to the CMS about the ISB changes
+  handling status.
+* IC_NB_Global now have "nb_ic_cfg" and "sb_ic_cfg" columns for
+  for ISB informational status.
+* IC_SB_Global now have "nb_ic_cfg" column for ISB informational status.
+* Availability_Zone now have "nb_ic_cfg" column for local AZ
+  informational status.
 
 OVN v23.09.0 - 15 Sep 2023
 --
diff --git a/ovn-ic-nb.ovsschema b/ovn-ic-nb.ovsschema
index 894db8344..bee174357 100644
--- a/ovn-ic-nb.ovsschema
+++ b/ovn-ic-nb.ovsschema
@@ -1,10 +1,12 @@
 {
 "name": "OVN_IC_Northbound",
-"version": "1.0.0",
-"cksum": "45589876 3383",
+"version": "1.1.0",
+"cksum": "3964083684 3501",
 "tables": {
 "IC_NB_Global": {
 "columns": {
+"nb_ic_cfg": {"type": {"key": "integer"}},
+"sb_ic_cfg": {"type": {"key": "integer"}},
 "external_ids": {
 "type": {"key": "string", "value": "string",
  "min": 0, "max": "unlimited"}},
diff --git a/ovn-ic-nb.xml b/ovn-ic-nb.xml
index 8c53bec3b..2ae9bf6d5 100644
--- a/ovn-ic-nb.xml
+++ b/ovn-ic-nb.xml
@@ -36,6 +36,23 @@
   one row.
 
 
+
+  These columns allow a client to track the overall configuration state of
+  the system.
+
+  
+Sequence number for client to increment. When a client modifies the
+interconnect northbound database configuration and wishes to wait for
+OVN-ICs to handle this change and update the Interconnect
+southbound database, it may increment this sequence number.
+  
+  
+Sequence number that one OVN-IC sets to the value of
+ after waiting to all the OVN-ICs
+finish applying their changes to interconnect southbound database.
+  
+
+
 
   
 See External IDs at the beginning of this document.
diff --git a/ovn-ic-sb.ovsschema b/ovn-ic-sb.ovsschema
index 1d60b36d1..5baf141cf 100644
--- a/ovn-ic-sb.ovsschema
+++ b/ovn-ic-sb.ovsschema
@@ -1,10 +1,11 @@
 {
 "name": "OVN_IC_Southbound",
-"version": "1.1.1",
-"cksum": "3684563024 6914",
+"version": "1.2.0",
+"cksum": "1381014956 7032",
 "tables": {
 "IC_SB_Global": {
 "columns": {
+"nb_ic_cfg": {"type": {"key": "integer"}},
 "external_ids": {
 "type": {"key": "string", "value": "string",
  "min": 0, "max": "unlimited"}},
@@ -24,7 +25,8 @@
 "isRoot": true},
 "Availability_Zone": {
 "columns": {
-"name": {"type": "string"}},
+"name": {"type": "string"},
+"nb_ic_cfg": {"type": {"key": "integer"}}},
 "isRoot": true,
 "indexes": [["name"]]},
 "Gateway": {
diff --git a/ovn-ic-sb.xml b/ovn-ic-sb.xml
index f7e17e113..c3e7d2173 100644
--- a/ovn-ic-sb.xml
+++ b/ovn-ic-sb.xml
@@ -69,6 +69,21 @@
   one row.
 
 
+
+  This column allow a client to track the overall configuration state of
+  the system.
+
+  
+Sequence number for the configuration. When a CMS or
+ovn-ic-nbctl updates the Interconnect northbound database,
+it increments the nb_ic_cfg column in the
+NB_IC_Global table in the Interconnect northbound
+database. when OVN-ICs updates the southbound database to
+bring it up to date with these changes, one OVN-IC updates
+this column to the same value.
+  
+
+
 
   
 See External IDs at the beginning of this document.
@@ -102,6 +117,12 @@
 
   A name that uniquely identifies the availability zone.
 
+
+
+  This column is used by the OVN-IC to inform
+  that this IC instance is aligned with the changes in INB
+
+
   
 
   
-- 
2.34.3

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


[ovs-dev] [PATCH ovn 3/4] IC: Make it possible for CMS to detect when the ISB is up-to-date.

2023-12-20 Thread Mohammad Heib
Until now, there has been no reliable for the CMS to detect when
changes made to the INB configuration have been passed through
to the ISB, This commit adds this feature to the system,
by adding sequence numbers to the INB and ISB and adding code
in ovn-ic-nbctl, ovn-ic to keep those sequence numbers up-to-date.

The biggest user-visible change from this commit is a new option
'--wait' and new command 'sync' to ovn-ic-nbctl.
With --wait=sb, ovn-ic-nbctl now waits for ovn-ics to update the ISB
database.

Signed-off-by: Mohammad Heib 
---
 utilities/ovn-ic-nbctl.8.xml | 46 ++
 utilities/ovn-ic-nbctl.c | 76 +++-
 2 files changed, 120 insertions(+), 2 deletions(-)

diff --git a/utilities/ovn-ic-nbctl.8.xml b/utilities/ovn-ic-nbctl.8.xml
index 4a70994b8..ccfacfaff 100644
--- a/utilities/ovn-ic-nbctl.8.xml
+++ b/utilities/ovn-ic-nbctl.8.xml
@@ -123,9 +123,55 @@
   
 
 
+Synchronization Commands
+
+
+  sync
+  
+Ordinarily, --wait=sb only waits for changes by the 
current
+ovn-ic-nbctl invocation to take effect.
+This means that, if none of the commands supplied to
+ovn-ic-nbctl change the database, then the command does 
not
+wait at all.  With the sync command, however,
+ovn-ic-nbctl waits even for earlier changes to the 
database
+to propagate down to the southbound database, according to the 
argument of --wait.
+  
+
+
 Options
 
 
+  --no-wait | --wait=none
+  --wait=sb
+
+  
+
+  These options control whether and how ovn-ic-nbctl waits
+  for the OVN system to become up-to-date with changes made in an
+  ovn-ic-nbctl invocation.
+
+
+
+  By default, or if --no-wait or --wait=none,
+  ovn-ic-nbctl exits immediately after confirming that
+  changes have been committed to the Interconnect northbound database,
+  without waiting.
+
+
+
+  With --wait=sb, before ovn-ic-nbctl exits, 
it
+  waits for ovn-ics to bring the Interconnect southbound 
database
+  up-to-date with the Interconnect northbound database updates.
+
+
+
+  Ordinarily, --wait=sb only waits for changes by the 
current
+  ovn-ic-nbctl invocation to take effect.
+  This means that, if none of the commands supplied to 
ovn-ic-nbctl
+  change the database, then the command does not wait at all.
+  Use the sync command to override this behavior.
+
+  
 --db database
 
   The OVSDB database remote to contact.  If the OVN_IC_NB_DB
diff --git a/utilities/ovn-ic-nbctl.c b/utilities/ovn-ic-nbctl.c
index 721dc4586..2061b0c67 100644
--- a/utilities/ovn-ic-nbctl.c
+++ b/utilities/ovn-ic-nbctl.c
@@ -58,6 +58,13 @@ static bool oneline;
 /* --dry-run: Do not commit any changes. */
 static bool dry_run;
 
+/* --wait=TYPE: Wait for configuration change to take effect? */
+static enum nbctl_wait_type wait_type = NBCTL_WAIT_NONE;
+
+/* Should we wait (if specified by 'wait_type') even if the commands don't
+ * change the database at all */
+static bool force_wait = false;
+
 /* --timeout: Time to wait for a connection to 'db'. */
 static unsigned int timeout;
 
@@ -161,6 +168,8 @@ parse_options(int argc, char *argv[], struct shash 
*local_options)
 OPT_DB = UCHAR_MAX + 1,
 OPT_ONELINE,
 OPT_NO_SYSLOG,
+OPT_NO_WAIT,
+OPT_WAIT,
 OPT_DRY_RUN,
 OPT_LOCAL,
 OPT_COMMANDS,
@@ -173,6 +182,8 @@ parse_options(int argc, char *argv[], struct shash 
*local_options)
 static const struct option global_long_options[] = {
 {"db", required_argument, NULL, OPT_DB},
 {"no-syslog", no_argument, NULL, OPT_NO_SYSLOG},
+{"no-wait", no_argument, NULL, OPT_NO_WAIT},
+{"wait", required_argument, NULL, OPT_WAIT},
 {"dry-run", no_argument, NULL, OPT_DRY_RUN},
 {"oneline", no_argument, NULL, OPT_ONELINE},
 {"timeout", required_argument, NULL, 't'},
@@ -234,7 +245,19 @@ parse_options(int argc, char *argv[], struct shash 
*local_options)
 case OPT_DRY_RUN:
 dry_run = true;
 break;
-
+case OPT_NO_WAIT:
+wait_type = NBCTL_WAIT_NONE;
+break;
+case OPT_WAIT:
+if (!strcmp(optarg, "none")) {
+wait_type = NBCTL_WAIT_NONE;
+} else if (!strcmp(optarg, "sb")) {
+wait_type = NBCTL_WAIT_SB;
+} else {
+ctl_fatal("argument to --wait must be "
+  "\"none\", \"sb\" ");
+}
+break;
 case OPT_LOCAL:
 if (shash_find(local_options, options[idx].name)) {
 ctl_fatal(&quo

[ovs-dev] [PATCH ovn 1/4] IC: interconnect DBs add basic Information Flow columns

2023-12-20 Thread Mohammad Heib
Add basic flow columns to interconnect northbound DB and
interconnect Southbound DB.

Those columns will be used by future patches to add basic
support for Information Flow in OVN  interconnect.

Signed-off-by: Mohammad Heib 
---
 NEWS|  8 
 ovn-ic-nb.ovsschema |  6 --
 ovn-ic-nb.xml   | 17 +
 ovn-ic-sb.ovsschema |  8 +---
 ovn-ic-sb.xml   | 20 
 5 files changed, 54 insertions(+), 5 deletions(-)

diff --git a/NEWS b/NEWS
index acb3b854f..a715c1545 100644
--- a/NEWS
+++ b/NEWS
@@ -10,6 +10,14 @@ Post v23.09.0
 external_ids:ovn-openflow-probe-interval configuration option for
 ovn-controller no longer matters and is ignored.
   - Enable PMTU discovery on geneve tunnels for E/W traffic.
+  - OVN Interconnection:
+* INB provides basic feedback to the CMS about the ISB changes
+  handling status.
+* IC_NB_Global now have "nb_ic_cfg" and "sb_ic_cfg" columns for
+  for ISB informational status.
+* IC_SB_Global now have "nb_ic_cfg" column for ISB informational status.
+* Availability_Zone now have "nb_ic_cfg" column for local AZ
+  informational status.
 
 OVN v23.09.0 - 15 Sep 2023
 --
diff --git a/ovn-ic-nb.ovsschema b/ovn-ic-nb.ovsschema
index 894db8344..bee174357 100644
--- a/ovn-ic-nb.ovsschema
+++ b/ovn-ic-nb.ovsschema
@@ -1,10 +1,12 @@
 {
 "name": "OVN_IC_Northbound",
-"version": "1.0.0",
-"cksum": "45589876 3383",
+"version": "1.1.0",
+"cksum": "3964083684 3501",
 "tables": {
 "IC_NB_Global": {
 "columns": {
+"nb_ic_cfg": {"type": {"key": "integer"}},
+"sb_ic_cfg": {"type": {"key": "integer"}},
 "external_ids": {
 "type": {"key": "string", "value": "string",
  "min": 0, "max": "unlimited"}},
diff --git a/ovn-ic-nb.xml b/ovn-ic-nb.xml
index 8c53bec3b..2ae9bf6d5 100644
--- a/ovn-ic-nb.xml
+++ b/ovn-ic-nb.xml
@@ -36,6 +36,23 @@
   one row.
 
 
+
+  These columns allow a client to track the overall configuration state of
+  the system.
+
+  
+Sequence number for client to increment. When a client modifies the
+interconnect northbound database configuration and wishes to wait for
+OVN-ICs to handle this change and update the Interconnect
+southbound database, it may increment this sequence number.
+  
+  
+Sequence number that one OVN-IC sets to the value of
+ after waiting to all the OVN-ICs
+finish applying their changes to interconnect southbound database.
+  
+
+
 
   
 See External IDs at the beginning of this document.
diff --git a/ovn-ic-sb.ovsschema b/ovn-ic-sb.ovsschema
index 1d60b36d1..5baf141cf 100644
--- a/ovn-ic-sb.ovsschema
+++ b/ovn-ic-sb.ovsschema
@@ -1,10 +1,11 @@
 {
 "name": "OVN_IC_Southbound",
-"version": "1.1.1",
-"cksum": "3684563024 6914",
+"version": "1.2.0",
+"cksum": "1381014956 7032",
 "tables": {
 "IC_SB_Global": {
 "columns": {
+"nb_ic_cfg": {"type": {"key": "integer"}},
 "external_ids": {
 "type": {"key": "string", "value": "string",
  "min": 0, "max": "unlimited"}},
@@ -24,7 +25,8 @@
 "isRoot": true},
 "Availability_Zone": {
 "columns": {
-"name": {"type": "string"}},
+"name": {"type": "string"},
+"nb_ic_cfg": {"type": {"key": "integer"}}},
 "isRoot": true,
 "indexes": [["name"]]},
 "Gateway": {
diff --git a/ovn-ic-sb.xml b/ovn-ic-sb.xml
index f7e17e113..0368315c7 100644
--- a/ovn-ic-sb.xml
+++ b/ovn-ic-sb.xml
@@ -69,6 +69,20 @@
   one row.
 
 
+
+  This column allow a client to track the overall configuration state of
+  the system.
+
+  
+Sequence number for the configuration. When a CMS or
+ovn-ic-nbctl updates the Interconnect northbound database,
+it increments the nb_ic_cfg column in the 
NB_IC_Global
+table in the Interconnect northbound database. when 
OVN-ICs updates
+the southbound database to bring it up to date with these changes, one
+OVN-IC updates this column to the same value.
+  
+
+
 
   
 See External IDs at the beginning of this document.
@@ -102,6 +116,12 @@
 
   A name that uniquely identifies the availability zone.
 
+
+
+  This column is used by the OVN-IC to inform
+  that this IC instance is aligned with the changes in INB
+
+
   
 
   
-- 
2.34.3

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


[ovs-dev] [PATCH ovn 2/4] ovn-ic: implement basic INB change handling status

2023-12-20 Thread Mohammad Heib
This patch implements a basic sequence number protocol
that can be used by CMS to determine if the changes
applied to INB are successfully propagated to ISB.

The implementation of this patch relies on OVN-ICs
instances to update the ISB by adding a per AZ a nb_ic_cfg
counter that will be updated by the OVN-IC once it is done
and commit all needed changes to the ISB, and according to this
AZ:nb_ic_cfg the ISB and INB will be updating about the status
of the changes.

Signed-off-by: Mohammad Heib 
---
 ic/ovn-ic.c | 98 +
 1 file changed, 92 insertions(+), 6 deletions(-)

diff --git a/ic/ovn-ic.c b/ic/ovn-ic.c
index 12e2729ce..b08b0e2d4 100644
--- a/ic/ovn-ic.c
+++ b/ic/ovn-ic.c
@@ -1786,16 +1786,96 @@ route_run(struct ic_context *ctx,
 hmap_destroy(_lrs);
 }
 
+/*
+ * This function implements a sequence number protocol that can be used by
+ * the INB end user to verify that ISB is synced with all the changes that
+ * are done be the user/AZs-controllers:
+ *
+ * Since we have multiple IC instances running in different regions
+ * we can't rely on one of them to update the ISB and sync that update
+ * to INB since other ICs can make changes in parallel.
+ * So to have a sequence number protocol working properly we must
+ * make sure that all the IC instances are synced with the ISB first
+ * and then update the INB.
+ *
+ * To guarantee that all instances are synced with ISB first, each IC
+ * will do the following steps:
+ *
+ * 1. when local ovn-ic sees that INB:nb_ic_cfg has updated we will set
+ *the ic_sb_loop->next_cfg to match the INB:nb_ic_cfg and increment
+ *the value of AZ:nb_ic_cfg and wait until we get confirmation from
+ *the server.
+ *
+ * 2. once this IC instance changes for ISB are committed successfully
+ *(next loop), the value of cur_cfg will be updated to match
+ *the INB:nb_ic_cfg that indicate that our local instance is up to date
+ *and no more changes need to be done for ISB.
+ *
+ * 3. validate that the AZ:nb_ic_cfg to match the INB:nb_ic_cfg.
+ *
+ * 4. Go through all the AZs and check if all have the same value of
+ *AZ:nb_ic_cfg that means all the AZs are done with ISB changes and ISB are
+ *up to date with INB, so we can set the values of ISB:nb_ic_cfg to
+ *INB:nb_ic_cfg and INB:sb_ic_cfg to INB:nb_ic_cfg.
+ */
 static void
-ovn_db_run(struct ic_context *ctx)
+update_sequence_numbers(const struct icsbrec_availability_zone *az,
+struct ic_context *ctx,
+struct ovsdb_idl_loop *ic_sb_loop)
 {
-const struct icsbrec_availability_zone *az = az_run(ctx);
-VLOG_DBG("Availability zone: %s", az ? az->name : "not created yet.");
+bool azs_cfg_equals = true;
 
-if (!az) {
-return;
+if (ctx->ovnisb_txn && ctx->ovninb_txn) {
+const struct icnbrec_ic_nb_global *ic_nb = icnbrec_ic_nb_global_first(
+   ctx->ovninb_idl);
+if (!ic_nb) {
+ic_nb = icnbrec_ic_nb_global_insert(ctx->ovninb_txn);
+}
+const struct icsbrec_ic_sb_global *ic_sb = icsbrec_ic_sb_global_first(
+   ctx->ovnisb_idl);
+if (!ic_sb) {
+ic_sb = icsbrec_ic_sb_global_insert(ctx->ovnisb_txn);
+}
+
+if ((ic_nb->nb_ic_cfg != ic_sb->nb_ic_cfg) &&
+  (ic_nb->nb_ic_cfg != az->nb_ic_cfg)) {
+/* Deal with potential overflows. */
+if (az->nb_ic_cfg == LLONG_MAX) {
+icsbrec_availability_zone_set_nb_ic_cfg(az, 0);
+}
+ic_sb_loop->next_cfg = ic_nb->nb_ic_cfg;
+ovsdb_idl_txn_increment(ctx->ovnisb_txn, >header_,
+   _availability_zone_col_nb_ic_cfg, true);
+goto done;
+}
+
+/* handle cases where accidentally AZ:ic_nb_cfg exceeds
+ * the INB:ic_nb_cfg.
+ */
+if (az->nb_ic_cfg != ic_sb_loop->cur_cfg) {
+icsbrec_availability_zone_set_nb_ic_cfg(az, ic_sb_loop->cur_cfg);
+goto done;
+}
+
+const struct icsbrec_availability_zone *other_az;
+ICSBREC_AVAILABILITY_ZONE_FOR_EACH (other_az, ctx->ovnisb_idl) {
+if (other_az->nb_ic_cfg != az->nb_ic_cfg) {
+azs_cfg_equals = false;
+}
+}
+
+if (azs_cfg_equals && (ic_nb->nb_ic_cfg != ic_sb->nb_ic_cfg)) {
+icsbrec_ic_sb_global_set_nb_ic_cfg(ic_sb, az->nb_ic_cfg);
+icnbrec_ic_nb_global_set_sb_ic_cfg(ic_nb, az->nb_ic_cfg);
+}
 }
+done: ;
+}
 
+static void
+ovn_db_run(struct ic_context *ctx,
+   const struct icsbrec_availability_zone *az)
+{
 ts_run(ctx);
 gateway_run(ctx, az);
 port_binding_

[ovs-dev] [PATCH ovn 4/4] ic/tests: add unit test for ic sync command

2023-12-20 Thread Mohammad Heib
add unit test that check validate that sync command
sync ISB properly

Signed-off-by: Mohammad Heib 
---
 tests/ovn-ic.at | 22 ++
 1 file changed, 22 insertions(+)

diff --git a/tests/ovn-ic.at b/tests/ovn-ic.at
index 5cc504e17..7464658ff 100644
--- a/tests/ovn-ic.at
+++ b/tests/ovn-ic.at
@@ -1297,3 +1297,25 @@ OVN_CLEANUP_IC([az1], [az2])
 
 AT_CLEANUP
 ])
+
+AT_SETUP([ovn-ic -- sync ISB status to INB])
+ovn_init_ic_db
+net_add n1
+
+ovn_start az1
+sim_add gw-az1
+as gw-az1
+
+check ovs-vsctl add-br br-phys
+ovn_az_attach az1 n1 br-phys 192.168.1.1
+check ovs-vsctl set open . external-ids:ovn-is-interconn=true
+
+ovn-ic-nbctl --wait=sb sync
+set -- $(ovn-ic-nbctl get ic_nb_global . nb_ic_cfg sb_ic_cfg)
+AS_VAR_SET([ic_nb_cfg], [$1])
+AS_VAR_SET([ic_sb_cfg], [$2])
+check test $ic_nb_cfg == $ic_sb_cfg
+
+OVN_CLEANUP_IC([az1])
+AT_CLEANUP
+])
-- 
2.34.3

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


[ovs-dev] [PATCH ovn] ovn-ic: handle NB:name updates properly

2023-12-18 Thread Mohammad Heib
When the user updates the NB_GLOBAL.name after registering
to IC Databases if the user already has defined chassis as a gateway
that will cause ovn-ic instance to run in an infinity loop trying
to update the gateways and insert the current gateway to the SB.chassis
tables as a remote chassis (we match on the new AZ ) which will fail since
we already have this chassis with is-interconn in local SB.

This patch aims to fix the above issues by updating the AZ.name only
when the user updates the NB.name locally.

Signed-off-by: Mohammad Heib 
---
 ic/ovn-ic.c | 10 +++---
 tests/ovn-ic.at | 23 +++
 2 files changed, 30 insertions(+), 3 deletions(-)

diff --git a/ic/ovn-ic.c b/ic/ovn-ic.c
index 8ceb34d7c..12e2729ce 100644
--- a/ic/ovn-ic.c
+++ b/ic/ovn-ic.c
@@ -132,14 +132,18 @@ az_run(struct ic_context *ctx)
 return NULL;
 }
 
-/* Delete old AZ if name changes.  Note: if name changed when ovn-ic
- * is not running, one has to manually delete the old AZ with:
+/* Update old AZ if name changes.  Note: if name changed when ovn-ic
+ * is not running, one has to manually delete/update the old AZ with:
  * "ovn-ic-sbctl destroy avail ". */
 static char *az_name;
 const struct icsbrec_availability_zone *az;
 if (az_name && strcmp(az_name, nb_global->name)) {
 ICSBREC_AVAILABILITY_ZONE_FOR_EACH (az, ctx->ovnisb_idl) {
-if (!strcmp(az->name, az_name)) {
+/* AZ name update locally need to update az in ISB. */
+if (nb_global->name[0] && !strcmp(az->name, az_name)) {
+icsbrec_availability_zone_set_name(az, nb_global->name);
+break;
+} else if (!nb_global->name[0] && !strcmp(az->name, az_name)) {
 icsbrec_availability_zone_delete(az);
 break;
 }
diff --git a/tests/ovn-ic.at b/tests/ovn-ic.at
index d4c436f84..5cc504e17 100644
--- a/tests/ovn-ic.at
+++ b/tests/ovn-ic.at
@@ -28,7 +28,30 @@ availability-zone az3
 ])
 
 OVN_CLEANUP_IC([az1], [az2])
+AT_CLEANUP
+])
+
+
+AT_SETUP([ovn-ic -- AZ update in GW])
+ovn_init_ic_db
+net_add n1
 
+ovn_start az1
+sim_add gw-az1
+as gw-az1
+
+check ovs-vsctl add-br br-phys
+ovn_az_attach az1 n1 br-phys 192.168.1.1
+check ovs-vsctl set open . external-ids:ovn-is-interconn=true
+
+az_uuid=$(fetch_column ic-sb:availability-zone _uuid name="az1")
+ovn_as az1 ovn-nbctl set NB_Global . name="az2"
+wait_column "$az_uuid" ic-sb:availability-zone _uuid name="az2"
+
+# make sure that gateway still point to the same AZ with new name
+wait_column "$az_uuid" ic-sb:gateway availability_zone name="gw-az1"
+
+OVN_CLEANUP_IC([az1])
 AT_CLEANUP
 ])
 
-- 
2.34.3

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


[ovs-dev] [PATCH v5 1/2] mcast-snooping: Store IGMP/MLD protocol version.

2023-11-30 Thread Mohammad Heib
Store igmp/mld protocol version into the
mcast_group internally, the multicast snooping feature
is used by many OVS consumers and those consumers heavily rely
on the OVS implementation to manage/deal with mcast groups,
some of those consumers also need to deal/expose the mcast protocol
to the end user for debuggability purposes.

OVN for example needs to expose the protocol version to the end user
to match between the protocol version used in the OVN logical switches
and the uplink ports

Therefore, instead of implementing this in each OVS consumer that needs
to deal mcast group protocol version which will be very complicated
implementation since it rely on the OVS code, saving the protocol to
the mdb inside OVS will give that consumer access to the protocol version
very easily.

Signed-off-by: Mohammad Heib 
---
 lib/mcast-snooping.c | 20 +---
 lib/mcast-snooping.h | 21 ++---
 ofproto/ofproto-dpif-xlate.c | 10 --
 3 files changed, 39 insertions(+), 12 deletions(-)

diff --git a/lib/mcast-snooping.c b/lib/mcast-snooping.c
index 43805ae4d..5046e35d2 100644
--- a/lib/mcast-snooping.c
+++ b/lib/mcast-snooping.c
@@ -389,7 +389,8 @@ mcast_snooping_prune_expired(struct mcast_snooping *ms,
 bool
 mcast_snooping_add_group(struct mcast_snooping *ms,
  const struct in6_addr *addr,
- uint16_t vlan, void *port)
+ uint16_t vlan, void *port,
+ mcast_group_proto grp_proto)
 OVS_REQ_WRLOCK(ms->rwlock)
 {
 bool learned;
@@ -415,6 +416,7 @@ mcast_snooping_add_group(struct mcast_snooping *ms,
 hmap_insert(>table, >hmap_node, hash);
 grp->addr = *addr;
 grp->vlan = vlan;
+grp->protocol_version = grp_proto;
 ovs_list_init(>bundle_lru);
 learned = true;
 ms->need_revalidate = true;
@@ -431,17 +433,19 @@ mcast_snooping_add_group(struct mcast_snooping *ms,
 
 bool
 mcast_snooping_add_group4(struct mcast_snooping *ms, ovs_be32 ip4,
- uint16_t vlan, void *port)
+ uint16_t vlan, void *port,
+ mcast_group_proto grp_proto)
 OVS_REQ_WRLOCK(ms->rwlock)
 {
 struct in6_addr addr = in6_addr_mapped_ipv4(ip4);
-return mcast_snooping_add_group(ms, , vlan, port);
+return mcast_snooping_add_group(ms, , vlan, port, grp_proto);
 }
 
 int
 mcast_snooping_add_report(struct mcast_snooping *ms,
   const struct dp_packet *p,
-  uint16_t vlan, void *port)
+  uint16_t vlan, void *port,
+  mcast_group_proto grp_proto)
 {
 ovs_be32 ip4;
 size_t offset;
@@ -478,7 +482,7 @@ mcast_snooping_add_report(struct mcast_snooping *ms,
 || record->type == IGMPV3_CHANGE_TO_INCLUDE_MODE)) {
 ret = mcast_snooping_leave_group4(ms, ip4, vlan, port);
 } else {
-ret = mcast_snooping_add_group4(ms, ip4, vlan, port);
+ret = mcast_snooping_add_group4(ms, ip4, vlan, port, grp_proto);
 }
 if (ret) {
 count++;
@@ -513,7 +517,8 @@ mcast_snooping_add_mld(struct mcast_snooping *ms,
 
 switch (mld->type) {
 case MLD_REPORT:
-ret = mcast_snooping_add_group(ms, addr, vlan, port);
+ret = mcast_snooping_add_group(ms, addr, vlan, port,
+   MCAST_GROUP_MLDV1);
 if (ret) {
 count++;
 }
@@ -545,7 +550,8 @@ mcast_snooping_add_mld(struct mcast_snooping *ms,
 || record->type == IGMPV3_CHANGE_TO_INCLUDE_MODE)) {
 ret = mcast_snooping_leave_group(ms, addr, vlan, port);
 } else {
-ret = mcast_snooping_add_group(ms, addr, vlan, port);
+ret = mcast_snooping_add_group(ms, addr, vlan, port,
+   MCAST_GROUP_MLDV2);
 }
 if (ret) {
 count++;
diff --git a/lib/mcast-snooping.h b/lib/mcast-snooping.h
index f120405da..f54007740 100644
--- a/lib/mcast-snooping.h
+++ b/lib/mcast-snooping.h
@@ -39,6 +39,15 @@ struct mcast_snooping;
 /* Time, in seconds, before expiring a mrouter_port due to inactivity. */
 #define MCAST_MROUTER_PORT_IDLE_TIME 180
 
+/* Multicast group protocol. */
+typedef enum {
+MCAST_GROUP_IGMPV1 = 0,
+MCAST_GROUP_IGMPV2,
+MCAST_GROUP_IGMPV3,
+MCAST_GROUP_MLDV1,
+MCAST_GROUP_MLDV2,
+} mcast_group_proto;
+
 /* Multicast group entry.
  * Guarded by owning 'mcast_snooping''s rwlock. */
 struct mcast_group {
@@ -51,6 +60,9 @@ struct mcast_group {
 /* VLAN tag. */
 uint16_t vlan;
 
+/* Multicast group IPv6/IPv4 Protocol version IGMPv1,2,3 or MLDv1,2 */
+mcast_group_proto protocol_version;
+
 /* Node in parent struct mcast_snooping group_lru. */
 st

[ovs-dev] [PATCH v5 2/2] mcast-snooping: Add group protocol to mdb/show output.

2023-11-30 Thread Mohammad Heib
Expose the mcast group protocol via the mdb/show
command output.

Signed-off-by: Mohammad Heib 
---
 lib/mcast-snooping.c|  24 ++
 lib/mcast-snooping.h|   1 +
 ofproto/ofproto-dpif.c  |   6 ++-
 tests/mcast-snooping.at | 103 
 tests/stp.at|   6 +--
 5 files changed, 116 insertions(+), 24 deletions(-)

diff --git a/lib/mcast-snooping.c b/lib/mcast-snooping.c
index 5046e35d2..d72cac0a4 100644
--- a/lib/mcast-snooping.c
+++ b/lib/mcast-snooping.c
@@ -57,6 +57,30 @@ mcast_snooping_flood_unreg(const struct mcast_snooping *ms)
 return ms->flood_unreg;
 }
 
+char *
+mcast_snooping_group_proto_str(mcast_group_proto grp_proto)
+{
+switch (grp_proto) {
+case MCAST_GROUP_IGMPV1:
+return "IGMPv1";
+break;
+case MCAST_GROUP_IGMPV2:
+return "IGMPv2";
+break;
+case MCAST_GROUP_IGMPV3:
+return "IGMPv3";
+break;
+case MCAST_GROUP_MLDV1:
+return "MLDv1";
+break;
+case MCAST_GROUP_MLDV2:
+return "MLDv2";
+break;
+default:
+return "";
+}
+}
+
 bool
 mcast_snooping_is_query(ovs_be16 igmp_type)
 {
diff --git a/lib/mcast-snooping.h b/lib/mcast-snooping.h
index f54007740..4ab83b049 100644
--- a/lib/mcast-snooping.h
+++ b/lib/mcast-snooping.h
@@ -225,6 +225,7 @@ bool mcast_snooping_add_mrouter(struct mcast_snooping *ms, 
uint16_t vlan,
 OVS_REQ_WRLOCK(ms->rwlock);
 bool mcast_snooping_is_query(ovs_be16 igmp_type);
 bool mcast_snooping_is_membership(ovs_be16 igmp_type);
+char * mcast_snooping_group_proto_str(mcast_group_proto grp_proto);
 
 /* Flush. */
 void mcast_snooping_mdb_flush(struct mcast_snooping *ms);
diff --git a/ofproto/ofproto-dpif.c b/ofproto/ofproto-dpif.c
index 54e057d43..b116d84f9 100644
--- a/ofproto/ofproto-dpif.c
+++ b/ofproto/ofproto-dpif.c
@@ -6122,7 +6122,7 @@ ofproto_unixctl_mcast_snooping_show(struct unixctl_conn 
*conn,
 return;
 }
 
-ds_put_cstr(, " port  VLAN  GROUPAge\n");
+ds_put_cstr(, " port  VLAN  PROTO  GROUPAge\n");
 ovs_rwlock_rdlock(>ms->rwlock);
 LIST_FOR_EACH (grp, group_node, >ms->group_lru) {
 LIST_FOR_EACH(b, bundle_node, >bundle_lru) {
@@ -6131,7 +6131,9 @@ ofproto_unixctl_mcast_snooping_show(struct unixctl_conn 
*conn,
 bundle = b->port;
 ofputil_port_to_string(ofbundle_get_a_port(bundle)->up.ofp_port,
NULL, name, sizeof name);
-ds_put_format(, "%5s  %4d  ", name, grp->vlan);
+ds_put_format(, "%5s  %4d  %5s  ", name, grp->vlan,
+  mcast_snooping_group_proto_str(
+  grp->protocol_version));
 ipv6_format_mapped(>addr, );
 ds_put_format(, " %3d\n",
   mcast_bundle_age(ofproto->ms, b));
diff --git a/tests/mcast-snooping.at b/tests/mcast-snooping.at
index 890e6aca0..02be196e4 100644
--- a/tests/mcast-snooping.at
+++ b/tests/mcast-snooping.at
@@ -44,7 +44,7 @@ AT_CHECK([ovs-appctl netdev-dummy/receive p2 \
 
'01005e015c8a38552552810006c0080046c0002401027c00ac111c01e00194041164ec1e027d'])
 
 AT_CHECK([ovs-appctl mdb/show br0], [0], [dnl
- port  VLAN  GROUPAge
+ port  VLAN  PROTO  GROUPAge
 2  1725  querier   0
 2  1728  querier   0
 ])
@@ -75,7 +75,7 @@ AT_CHECK([ovs-appctl netdev-dummy/receive p2 \
 
'01005e015c8a38552552810006bd080046c0002401027f00ac111901e00194041164ec10027d'])
 
 AT_CHECK([ovs-appctl mdb/show br0], [0], [dnl
- port  VLAN  GROUPAge
+ port  VLAN  PROTO  GROUPAge
 ])
 
 
@@ -87,8 +87,8 @@ AT_CHECK([ovs-appctl netdev-dummy/receive p2 \
 
'ff0e4c67000c290e4c6786dd6021ff020001ff0e4c673a00050201008300e7b8ff020001ff0e4c67'])
 
 AT_CHECK([ovs-appctl mdb/show br0], [0], [dnl
- port  VLAN  GROUPAge
-2 0  ff02::1:ff0e:4c67   0
+ port  VLAN  PROTO  GROUPAge
+2 0  MLDv1  ff02::1:ff0e:4c67   0
 ])
 
 AT_CHECK([ovs-appctl mdb/flush br0], [0], [dnl
@@ -99,7 +99,7 @@ AT_CHECK([ovs-appctl netdev-dummy/receive p2 \
 
'ff0e4c67000c290e4c6786dd6021ff020001ff0e4c673a00050201008300e7b0ff020001ff0e4c67'])
 
 AT_CHECK([ovs-appctl mdb/show br0], [0], [dnl
- port  VLAN  GROUPAge
+ port  VLAN  PROTO  GROUPAge
 ])
 
 OVS_VSWITCHD_STOP
@@ -154,8 +154,8 @@ AT_CHECK([
 
'01005E010101000C29A027A10800451C00014002CBAEAC10221EE001

Re: [ovs-dev] [PATCH v4 1/2] mcast-snooping: Store IGMP/MLD protocol version.

2023-11-20 Thread Mohammad Heib
On Mon, Nov 20, 2023 at 6:09 PM Simon Horman  wrote:

> On Mon, Nov 20, 2023 at 04:22:44PM +0200, Mohammad Heib wrote:
> > Store the igmp/mld protocol version into the
> > mcast_group internally.
> >
> > This can be used by ovs consumers to update
> > about the igmp/mld version of each group.
>
> Thanks Mohammad,
>
> I see in patch 2/2 that the user can now gain access to the igmp/mld
> version of each group. But I am wondering if we could add some text
> to the commit message to explain, perhaps via an example, why
> a user might want such information.
>

Hi Simon,

Thank you for the review.
actually, i don't really have a good reason why the user will need the
group protocol in OVS stand-alone case,
but I'm trying to expand that here and save the protocol because i need it
in the OVN/OVS case where we store
each Mcast group information inside ovn-sb DB as raw in *the MCAST_GROUP*
table, and i have to expose a protocol version
for each Group in this table, cause OVN relies on the ovs mcast
implementation to maintain this table, i thought this would be the cleaner
way to accomplish that.

so now i don't really know which example can be good to add :(
do you think adding a small example of extracting the protocol will be good
enough?

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


[ovs-dev] [PATCH v4 2/2] mcast-snooping: Add group protocol to mdb/show output.

2023-11-20 Thread Mohammad Heib
Expose the mcast group protocol via the mdb/show
command output.

Signed-off-by: Mohammad Heib 
---
 lib/mcast-snooping.c| 24 ++
 lib/mcast-snooping.h|  1 +
 ofproto/ofproto-dpif.c  |  6 ++-
 tests/mcast-snooping.at | 99 ++---
 tests/stp.at|  6 +--
 5 files changed, 114 insertions(+), 22 deletions(-)

diff --git a/lib/mcast-snooping.c b/lib/mcast-snooping.c
index 99516bd43..1f4bcc865 100644
--- a/lib/mcast-snooping.c
+++ b/lib/mcast-snooping.c
@@ -57,6 +57,30 @@ mcast_snooping_flood_unreg(const struct mcast_snooping *ms)
 return ms->flood_unreg;
 }
 
+char *
+mcast_snooping_group_proto_str(mcast_group_proto grp_proto)
+{
+switch (grp_proto) {
+case MCAST_GROUP_IGMPV1:
+return "IGMPv1";
+break;
+case MCAST_GROUP_IGMPV2:
+return "IGMPv2";
+break;
+case MCAST_GROUP_IGMPV3:
+return "IGMPv3";
+break;
+case MCAST_GROUP_MLDV1:
+return "MLDv1";
+break;
+case MCAST_GROUP_MLDV2:
+return "MLDv2";
+break;
+default:
+return "";
+}
+}
+
 bool
 mcast_snooping_is_query(ovs_be16 igmp_type)
 {
diff --git a/lib/mcast-snooping.h b/lib/mcast-snooping.h
index f54007740..4ab83b049 100644
--- a/lib/mcast-snooping.h
+++ b/lib/mcast-snooping.h
@@ -225,6 +225,7 @@ bool mcast_snooping_add_mrouter(struct mcast_snooping *ms, 
uint16_t vlan,
 OVS_REQ_WRLOCK(ms->rwlock);
 bool mcast_snooping_is_query(ovs_be16 igmp_type);
 bool mcast_snooping_is_membership(ovs_be16 igmp_type);
+char * mcast_snooping_group_proto_str(mcast_group_proto grp_proto);
 
 /* Flush. */
 void mcast_snooping_mdb_flush(struct mcast_snooping *ms);
diff --git a/ofproto/ofproto-dpif.c b/ofproto/ofproto-dpif.c
index 54e057d43..b116d84f9 100644
--- a/ofproto/ofproto-dpif.c
+++ b/ofproto/ofproto-dpif.c
@@ -6122,7 +6122,7 @@ ofproto_unixctl_mcast_snooping_show(struct unixctl_conn 
*conn,
 return;
 }
 
-ds_put_cstr(, " port  VLAN  GROUPAge\n");
+ds_put_cstr(, " port  VLAN  PROTO  GROUPAge\n");
 ovs_rwlock_rdlock(>ms->rwlock);
 LIST_FOR_EACH (grp, group_node, >ms->group_lru) {
 LIST_FOR_EACH(b, bundle_node, >bundle_lru) {
@@ -6131,7 +6131,9 @@ ofproto_unixctl_mcast_snooping_show(struct unixctl_conn 
*conn,
 bundle = b->port;
 ofputil_port_to_string(ofbundle_get_a_port(bundle)->up.ofp_port,
NULL, name, sizeof name);
-ds_put_format(, "%5s  %4d  ", name, grp->vlan);
+ds_put_format(, "%5s  %4d  %5s  ", name, grp->vlan,
+  mcast_snooping_group_proto_str(
+  grp->protocol_version));
 ipv6_format_mapped(>addr, );
 ds_put_format(, " %3d\n",
   mcast_bundle_age(ofproto->ms, b));
diff --git a/tests/mcast-snooping.at b/tests/mcast-snooping.at
index d5b7c4774..dc20ac92f 100644
--- a/tests/mcast-snooping.at
+++ b/tests/mcast-snooping.at
@@ -44,7 +44,7 @@ AT_CHECK([ovs-appctl netdev-dummy/receive p2 \
 
'01005e015c8a38552552810006c0080046c0002401027c00ac111c01e00194041164ec1e027d'])
 
 AT_CHECK([ovs-appctl mdb/show br0], [0], [dnl
- port  VLAN  GROUPAge
+ port  VLAN  PROTO  GROUPAge
 2  1725  querier   0
 2  1728  querier   0
 ])
@@ -75,7 +75,7 @@ AT_CHECK([ovs-appctl netdev-dummy/receive p2 \
 
'01005e015c8a38552552810006bd080046c0002401027f00ac111901e00194041164ec10027d'])
 
 AT_CHECK([ovs-appctl mdb/show br0], [0], [dnl
- port  VLAN  GROUPAge
+ port  VLAN  PROTO  GROUPAge
 ])
 
 
@@ -87,8 +87,8 @@ AT_CHECK([ovs-appctl netdev-dummy/receive p2 \
 
'ff0e4c67000c290e4c6786dd6021ff020001ff0e4c673a00050201008300e7b8ff020001ff0e4c67'])
 
 AT_CHECK([ovs-appctl mdb/show br0], [0], [dnl
- port  VLAN  GROUPAge
-2 0  ff02::1:ff0e:4c67   0
+ port  VLAN  PROTO  GROUPAge
+2 0  MLDv1  ff02::1:ff0e:4c67   0
 ])
 
 AT_CHECK([ovs-appctl mdb/flush br0], [0], [dnl
@@ -99,7 +99,7 @@ AT_CHECK([ovs-appctl netdev-dummy/receive p2 \
 
'ff0e4c67000c290e4c6786dd6021ff020001ff0e4c673a00050201008300e7b0ff020001ff0e4c67'])
 
 AT_CHECK([ovs-appctl mdb/show br0], [0], [dnl
- port  VLAN  GROUPAge
+ port  VLAN  PROTO  GROUPAge
 ])
 
 OVS_VSWITCHD_STOP
@@ -145,9 +145,9 @@ AT_CHECK([
 ], [0])
 
 AT_CHECK([ovs-appctl mdb/show br0], [0], [dnl
- port  VLAN  GRO

[ovs-dev] [PATCH v4 1/2] mcast-snooping: Store IGMP/MLD protocol version.

2023-11-20 Thread Mohammad Heib
Store the igmp/mld protocol version into the
mcast_group internally.

This can be used by ovs consumers to update
about the igmp/mld version of each group.

Signed-off-by: Mohammad Heib 
---
 lib/mcast-snooping.c | 20 +---
 lib/mcast-snooping.h | 21 ++---
 ofproto/ofproto-dpif-xlate.c | 10 --
 3 files changed, 39 insertions(+), 12 deletions(-)

diff --git a/lib/mcast-snooping.c b/lib/mcast-snooping.c
index 029ca2855..99516bd43 100644
--- a/lib/mcast-snooping.c
+++ b/lib/mcast-snooping.c
@@ -389,7 +389,8 @@ mcast_snooping_prune_expired(struct mcast_snooping *ms,
 bool
 mcast_snooping_add_group(struct mcast_snooping *ms,
  const struct in6_addr *addr,
- uint16_t vlan, void *port)
+ uint16_t vlan, void *port,
+ mcast_group_proto grp_proto)
 OVS_REQ_WRLOCK(ms->rwlock)
 {
 bool learned;
@@ -415,6 +416,7 @@ mcast_snooping_add_group(struct mcast_snooping *ms,
 hmap_insert(>table, >hmap_node, hash);
 grp->addr = *addr;
 grp->vlan = vlan;
+grp->protocol_version = grp_proto;
 ovs_list_init(>bundle_lru);
 learned = true;
 ms->need_revalidate = true;
@@ -431,17 +433,19 @@ mcast_snooping_add_group(struct mcast_snooping *ms,
 
 bool
 mcast_snooping_add_group4(struct mcast_snooping *ms, ovs_be32 ip4,
- uint16_t vlan, void *port)
+ uint16_t vlan, void *port,
+ mcast_group_proto grp_proto)
 OVS_REQ_WRLOCK(ms->rwlock)
 {
 struct in6_addr addr = in6_addr_mapped_ipv4(ip4);
-return mcast_snooping_add_group(ms, , vlan, port);
+return mcast_snooping_add_group(ms, , vlan, port, grp_proto);
 }
 
 int
 mcast_snooping_add_report(struct mcast_snooping *ms,
   const struct dp_packet *p,
-  uint16_t vlan, void *port)
+  uint16_t vlan, void *port,
+  mcast_group_proto grp_proto)
 {
 ovs_be32 ip4;
 size_t offset;
@@ -478,7 +482,7 @@ mcast_snooping_add_report(struct mcast_snooping *ms,
 || record->type == IGMPV3_CHANGE_TO_INCLUDE_MODE)) {
 ret = mcast_snooping_leave_group4(ms, ip4, vlan, port);
 } else {
-ret = mcast_snooping_add_group4(ms, ip4, vlan, port);
+ret = mcast_snooping_add_group4(ms, ip4, vlan, port, grp_proto);
 }
 if (ret) {
 count++;
@@ -513,7 +517,8 @@ mcast_snooping_add_mld(struct mcast_snooping *ms,
 
 switch (mld->type) {
 case MLD_REPORT:
-ret = mcast_snooping_add_group(ms, addr, vlan, port);
+ret = mcast_snooping_add_group(ms, addr, vlan, port,
+   MCAST_GROUP_MLDV1);
 if (ret) {
 count++;
 }
@@ -545,7 +550,8 @@ mcast_snooping_add_mld(struct mcast_snooping *ms,
 || record->type == IGMPV3_CHANGE_TO_INCLUDE_MODE)) {
 ret = mcast_snooping_leave_group(ms, addr, vlan, port);
 } else {
-ret = mcast_snooping_add_group(ms, addr, vlan, port);
+ret = mcast_snooping_add_group(ms, addr, vlan, port,
+   MCAST_GROUP_MLDV2);
 }
 if (ret) {
 count++;
diff --git a/lib/mcast-snooping.h b/lib/mcast-snooping.h
index f120405da..f54007740 100644
--- a/lib/mcast-snooping.h
+++ b/lib/mcast-snooping.h
@@ -39,6 +39,15 @@ struct mcast_snooping;
 /* Time, in seconds, before expiring a mrouter_port due to inactivity. */
 #define MCAST_MROUTER_PORT_IDLE_TIME 180
 
+/* Multicast group protocol. */
+typedef enum {
+MCAST_GROUP_IGMPV1 = 0,
+MCAST_GROUP_IGMPV2,
+MCAST_GROUP_IGMPV3,
+MCAST_GROUP_MLDV1,
+MCAST_GROUP_MLDV2,
+} mcast_group_proto;
+
 /* Multicast group entry.
  * Guarded by owning 'mcast_snooping''s rwlock. */
 struct mcast_group {
@@ -51,6 +60,9 @@ struct mcast_group {
 /* VLAN tag. */
 uint16_t vlan;
 
+/* Multicast group IPv6/IPv4 Protocol version IGMPv1,2,3 or MLDv1,2 */
+mcast_group_proto protocol_version;
+
 /* Node in parent struct mcast_snooping group_lru. */
 struct ovs_list group_node OVS_GUARDED;
 
@@ -185,14 +197,17 @@ mcast_snooping_lookup4(const struct mcast_snooping *ms, 
ovs_be32 ip4,
 /* Learning. */
 bool mcast_snooping_add_group(struct mcast_snooping *ms,
   const struct in6_addr *addr,
-  uint16_t vlan, void *port)
+  uint16_t vlan, void *port,
+  mcast_group_proto grp_proto)
 OVS_REQ_WRLOCK(ms->rwlock);
 bool mcast_snooping_add_group4(struct mcast_snooping *ms, ovs_be32 ip4,
-   uint16_t vlan, void *port)
+ 

Re: [ovs-dev] [PATCH v2] mcast-snooping: Store IGMP/MLD protocol version.

2023-11-19 Thread Mohammad Heib
Hi Eelco,
On Thu, Nov 16, 2023 at 5:23 PM Eelco Chaudron  wrote:

>
>
> On 16 Nov 2023, at 15:58, Eelco Chaudron wrote:
>
> > On 16 Nov 2023, at 15:08, Mohammad Heib wrote:
> >
> >> Store the igmp/mld protocol version into the
> >> mcast_group internally.
> >>
> >> This can be used by ovs consumers to update
> >> about the igmp/mld version of each group.
> >>
> >> Signed-off-by: Mohammad Heib 
> >
> > Hi Mohammad,
> >
> > Thanks for the patch, I have not reviewed the actual code yet, but it
> would be good to include a use case for this patch (maybe expand this to a
> series). This way it’s clear why we need to store this information.
> >
> > Cheers,
> >
> > Eelco
>
> After a quick code review I have one comment, see below.
>
> >> ---
> >>  lib/mcast-snooping.c | 16 +---
> >>  lib/mcast-snooping.h |  9 ++---
> >>  ofproto/ofproto-dpif-xlate.c |  6 --
> >>  3 files changed, 19 insertions(+), 12 deletions(-)
> >>
> >> diff --git a/lib/mcast-snooping.c b/lib/mcast-snooping.c
> >> index 029ca2855..926daf9ac 100644
> >> --- a/lib/mcast-snooping.c
> >> +++ b/lib/mcast-snooping.c
> >> @@ -389,7 +389,7 @@ mcast_snooping_prune_expired(struct mcast_snooping
> *ms,
> >>  bool
> >>  mcast_snooping_add_group(struct mcast_snooping *ms,
> >>   const struct in6_addr *addr,
> >> - uint16_t vlan, void *port)
> >> + uint16_t vlan, void *port, uint8_t grp_proto)
> >>  OVS_REQ_WRLOCK(ms->rwlock)
> >>  {
> >>  bool learned;
> >> @@ -415,6 +415,7 @@ mcast_snooping_add_group(struct mcast_snooping *ms,
> >>  hmap_insert(>table, >hmap_node, hash);
> >>  grp->addr = *addr;
> >>  grp->vlan = vlan;
> >> +grp->protocol_version = grp_proto;
> >>  ovs_list_init(>bundle_lru);
> >>  learned = true;
> >>  ms->need_revalidate = true;
> >> @@ -431,17 +432,17 @@ mcast_snooping_add_group(struct mcast_snooping
> *ms,
> >>
> >>  bool
> >>  mcast_snooping_add_group4(struct mcast_snooping *ms, ovs_be32 ip4,
> >> - uint16_t vlan, void *port)
> >> + uint16_t vlan, void *port, uint8_t grp_proto)
> >>  OVS_REQ_WRLOCK(ms->rwlock)
> >>  {
> >>  struct in6_addr addr = in6_addr_mapped_ipv4(ip4);
> >> -return mcast_snooping_add_group(ms, , vlan, port);
> >> +return mcast_snooping_add_group(ms, , vlan, port, grp_proto);
> >>  }
> >>
> >>  int
> >>  mcast_snooping_add_report(struct mcast_snooping *ms,
> >>const struct dp_packet *p,
> >> -  uint16_t vlan, void *port)
> >> +  uint16_t vlan, void *port, uint8_t grp_proto)
> >>  {
> >>  ovs_be32 ip4;
> >>  size_t offset;
> >> @@ -478,7 +479,7 @@ mcast_snooping_add_report(struct mcast_snooping *ms,
> >>  || record->type == IGMPV3_CHANGE_TO_INCLUDE_MODE)) {
> >>  ret = mcast_snooping_leave_group4(ms, ip4, vlan, port);
> >>  } else {
> >> -ret = mcast_snooping_add_group4(ms, ip4, vlan, port);
> >> +ret = mcast_snooping_add_group4(ms, ip4, vlan, port,
> grp_proto);
> >>  }
> >>  if (ret) {
> >>  count++;
> >> @@ -513,7 +514,7 @@ mcast_snooping_add_mld(struct mcast_snooping *ms,
> >>
> >>  switch (mld->type) {
> >>  case MLD_REPORT:
> >> -ret = mcast_snooping_add_group(ms, addr, vlan, port);
> >> +ret = mcast_snooping_add_group(ms, addr, vlan, port,
> MLD_REPORT);
> >>  if (ret) {
> >>  count++;
> >>  }
> >> @@ -545,7 +546,8 @@ mcast_snooping_add_mld(struct mcast_snooping *ms,
> >>  || record->type ==
> IGMPV3_CHANGE_TO_INCLUDE_MODE)) {
> >>  ret = mcast_snooping_leave_group(ms, addr, vlan,
> port);
> >>  } else {
> >> -ret = mcast_snooping_add_group(ms, addr, vlan,
> port);
> >> +ret = mcast_snooping_add_group(ms, addr, vlan,
> port,
> >> +   MLD2_REPORT);
>

[ovs-dev] [PATCH v3 2/2] mcast-snooping: Add group protocol to mdb/show output.

2023-11-19 Thread Mohammad Heib
Expose the mcast group protocol via the mdb/show
command output.

Signed-off-by: Mohammad Heib 
---
 lib/mcast-snooping.c| 24 ++
 lib/mcast-snooping.h|  1 +
 ofproto/ofproto-dpif.c  |  6 ++-
 tests/mcast-snooping.at | 99 ++---
 tests/stp.at|  6 +--
 5 files changed, 114 insertions(+), 22 deletions(-)

diff --git a/lib/mcast-snooping.c b/lib/mcast-snooping.c
index 99516bd43..1f4bcc865 100644
--- a/lib/mcast-snooping.c
+++ b/lib/mcast-snooping.c
@@ -57,6 +57,30 @@ mcast_snooping_flood_unreg(const struct mcast_snooping *ms)
 return ms->flood_unreg;
 }
 
+char *
+mcast_snooping_group_proto_str(mcast_group_proto grp_proto)
+{
+switch (grp_proto) {
+case MCAST_GROUP_IGMPV1:
+return "IGMPv1";
+break;
+case MCAST_GROUP_IGMPV2:
+return "IGMPv2";
+break;
+case MCAST_GROUP_IGMPV3:
+return "IGMPv3";
+break;
+case MCAST_GROUP_MLDV1:
+return "MLDv1";
+break;
+case MCAST_GROUP_MLDV2:
+return "MLDv2";
+break;
+default:
+return "";
+}
+}
+
 bool
 mcast_snooping_is_query(ovs_be16 igmp_type)
 {
diff --git a/lib/mcast-snooping.h b/lib/mcast-snooping.h
index f54007740..4ab83b049 100644
--- a/lib/mcast-snooping.h
+++ b/lib/mcast-snooping.h
@@ -225,6 +225,7 @@ bool mcast_snooping_add_mrouter(struct mcast_snooping *ms, 
uint16_t vlan,
 OVS_REQ_WRLOCK(ms->rwlock);
 bool mcast_snooping_is_query(ovs_be16 igmp_type);
 bool mcast_snooping_is_membership(ovs_be16 igmp_type);
+char * mcast_snooping_group_proto_str(mcast_group_proto grp_proto);
 
 /* Flush. */
 void mcast_snooping_mdb_flush(struct mcast_snooping *ms);
diff --git a/ofproto/ofproto-dpif.c b/ofproto/ofproto-dpif.c
index 54e057d43..b116d84f9 100644
--- a/ofproto/ofproto-dpif.c
+++ b/ofproto/ofproto-dpif.c
@@ -6122,7 +6122,7 @@ ofproto_unixctl_mcast_snooping_show(struct unixctl_conn 
*conn,
 return;
 }
 
-ds_put_cstr(, " port  VLAN  GROUPAge\n");
+ds_put_cstr(, " port  VLAN  PROTO  GROUPAge\n");
 ovs_rwlock_rdlock(>ms->rwlock);
 LIST_FOR_EACH (grp, group_node, >ms->group_lru) {
 LIST_FOR_EACH(b, bundle_node, >bundle_lru) {
@@ -6131,7 +6131,9 @@ ofproto_unixctl_mcast_snooping_show(struct unixctl_conn 
*conn,
 bundle = b->port;
 ofputil_port_to_string(ofbundle_get_a_port(bundle)->up.ofp_port,
NULL, name, sizeof name);
-ds_put_format(, "%5s  %4d  ", name, grp->vlan);
+ds_put_format(, "%5s  %4d  %5s  ", name, grp->vlan,
+  mcast_snooping_group_proto_str(
+  grp->protocol_version));
 ipv6_format_mapped(>addr, );
 ds_put_format(, " %3d\n",
   mcast_bundle_age(ofproto->ms, b));
diff --git a/tests/mcast-snooping.at b/tests/mcast-snooping.at
index d5b7c4774..dc20ac92f 100644
--- a/tests/mcast-snooping.at
+++ b/tests/mcast-snooping.at
@@ -44,7 +44,7 @@ AT_CHECK([ovs-appctl netdev-dummy/receive p2 \
 
'01005e015c8a38552552810006c0080046c0002401027c00ac111c01e00194041164ec1e027d'])
 
 AT_CHECK([ovs-appctl mdb/show br0], [0], [dnl
- port  VLAN  GROUPAge
+ port  VLAN  PROTO  GROUPAge
 2  1725  querier   0
 2  1728  querier   0
 ])
@@ -75,7 +75,7 @@ AT_CHECK([ovs-appctl netdev-dummy/receive p2 \
 
'01005e015c8a38552552810006bd080046c0002401027f00ac111901e00194041164ec10027d'])
 
 AT_CHECK([ovs-appctl mdb/show br0], [0], [dnl
- port  VLAN  GROUPAge
+ port  VLAN  PROTO  GROUPAge
 ])
 
 
@@ -87,8 +87,8 @@ AT_CHECK([ovs-appctl netdev-dummy/receive p2 \
 
'ff0e4c67000c290e4c6786dd6021ff020001ff0e4c673a00050201008300e7b8ff020001ff0e4c67'])
 
 AT_CHECK([ovs-appctl mdb/show br0], [0], [dnl
- port  VLAN  GROUPAge
-2 0  ff02::1:ff0e:4c67   0
+ port  VLAN  PROTO  GROUPAge
+2 0  MLDv1  ff02::1:ff0e:4c67   0
 ])
 
 AT_CHECK([ovs-appctl mdb/flush br0], [0], [dnl
@@ -99,7 +99,7 @@ AT_CHECK([ovs-appctl netdev-dummy/receive p2 \
 
'ff0e4c67000c290e4c6786dd6021ff020001ff0e4c673a00050201008300e7b0ff020001ff0e4c67'])
 
 AT_CHECK([ovs-appctl mdb/show br0], [0], [dnl
- port  VLAN  GROUPAge
+ port  VLAN  PROTO  GROUPAge
 ])
 
 OVS_VSWITCHD_STOP
@@ -145,9 +145,9 @@ AT_CHECK([
 ], [0])
 
 AT_CHECK([ovs-appctl mdb/show br0], [0], [dnl
- port  VLAN  GRO

[ovs-dev] [PATCH v3 1/2] mcast-snooping: Store IGMP/MLD protocol version.

2023-11-19 Thread Mohammad Heib
Store the igmp/mld protocol version into the
mcast_group internally.

This can be used by ovs consumers to update
about the igmp/mld version of each group.

Signed-off-by: Mohammad Heib 
---
 lib/mcast-snooping.c | 20 +---
 lib/mcast-snooping.h | 21 ++---
 ofproto/ofproto-dpif-xlate.c | 10 --
 3 files changed, 39 insertions(+), 12 deletions(-)

diff --git a/lib/mcast-snooping.c b/lib/mcast-snooping.c
index 029ca2855..99516bd43 100644
--- a/lib/mcast-snooping.c
+++ b/lib/mcast-snooping.c
@@ -389,7 +389,8 @@ mcast_snooping_prune_expired(struct mcast_snooping *ms,
 bool
 mcast_snooping_add_group(struct mcast_snooping *ms,
  const struct in6_addr *addr,
- uint16_t vlan, void *port)
+ uint16_t vlan, void *port,
+ mcast_group_proto grp_proto)
 OVS_REQ_WRLOCK(ms->rwlock)
 {
 bool learned;
@@ -415,6 +416,7 @@ mcast_snooping_add_group(struct mcast_snooping *ms,
 hmap_insert(>table, >hmap_node, hash);
 grp->addr = *addr;
 grp->vlan = vlan;
+grp->protocol_version = grp_proto;
 ovs_list_init(>bundle_lru);
 learned = true;
 ms->need_revalidate = true;
@@ -431,17 +433,19 @@ mcast_snooping_add_group(struct mcast_snooping *ms,
 
 bool
 mcast_snooping_add_group4(struct mcast_snooping *ms, ovs_be32 ip4,
- uint16_t vlan, void *port)
+ uint16_t vlan, void *port,
+ mcast_group_proto grp_proto)
 OVS_REQ_WRLOCK(ms->rwlock)
 {
 struct in6_addr addr = in6_addr_mapped_ipv4(ip4);
-return mcast_snooping_add_group(ms, , vlan, port);
+return mcast_snooping_add_group(ms, , vlan, port, grp_proto);
 }
 
 int
 mcast_snooping_add_report(struct mcast_snooping *ms,
   const struct dp_packet *p,
-  uint16_t vlan, void *port)
+  uint16_t vlan, void *port,
+  mcast_group_proto grp_proto)
 {
 ovs_be32 ip4;
 size_t offset;
@@ -478,7 +482,7 @@ mcast_snooping_add_report(struct mcast_snooping *ms,
 || record->type == IGMPV3_CHANGE_TO_INCLUDE_MODE)) {
 ret = mcast_snooping_leave_group4(ms, ip4, vlan, port);
 } else {
-ret = mcast_snooping_add_group4(ms, ip4, vlan, port);
+ret = mcast_snooping_add_group4(ms, ip4, vlan, port, grp_proto);
 }
 if (ret) {
 count++;
@@ -513,7 +517,8 @@ mcast_snooping_add_mld(struct mcast_snooping *ms,
 
 switch (mld->type) {
 case MLD_REPORT:
-ret = mcast_snooping_add_group(ms, addr, vlan, port);
+ret = mcast_snooping_add_group(ms, addr, vlan, port,
+   MCAST_GROUP_MLDV1);
 if (ret) {
 count++;
 }
@@ -545,7 +550,8 @@ mcast_snooping_add_mld(struct mcast_snooping *ms,
 || record->type == IGMPV3_CHANGE_TO_INCLUDE_MODE)) {
 ret = mcast_snooping_leave_group(ms, addr, vlan, port);
 } else {
-ret = mcast_snooping_add_group(ms, addr, vlan, port);
+ret = mcast_snooping_add_group(ms, addr, vlan, port,
+   MCAST_GROUP_MLDV2);
 }
 if (ret) {
 count++;
diff --git a/lib/mcast-snooping.h b/lib/mcast-snooping.h
index f120405da..f54007740 100644
--- a/lib/mcast-snooping.h
+++ b/lib/mcast-snooping.h
@@ -39,6 +39,15 @@ struct mcast_snooping;
 /* Time, in seconds, before expiring a mrouter_port due to inactivity. */
 #define MCAST_MROUTER_PORT_IDLE_TIME 180
 
+/* Multicast group protocol. */
+typedef enum {
+MCAST_GROUP_IGMPV1 = 0,
+MCAST_GROUP_IGMPV2,
+MCAST_GROUP_IGMPV3,
+MCAST_GROUP_MLDV1,
+MCAST_GROUP_MLDV2,
+} mcast_group_proto;
+
 /* Multicast group entry.
  * Guarded by owning 'mcast_snooping''s rwlock. */
 struct mcast_group {
@@ -51,6 +60,9 @@ struct mcast_group {
 /* VLAN tag. */
 uint16_t vlan;
 
+/* Multicast group IPv6/IPv4 Protocol version IGMPv1,2,3 or MLDv1,2 */
+mcast_group_proto protocol_version;
+
 /* Node in parent struct mcast_snooping group_lru. */
 struct ovs_list group_node OVS_GUARDED;
 
@@ -185,14 +197,17 @@ mcast_snooping_lookup4(const struct mcast_snooping *ms, 
ovs_be32 ip4,
 /* Learning. */
 bool mcast_snooping_add_group(struct mcast_snooping *ms,
   const struct in6_addr *addr,
-  uint16_t vlan, void *port)
+  uint16_t vlan, void *port,
+  mcast_group_proto grp_proto)
 OVS_REQ_WRLOCK(ms->rwlock);
 bool mcast_snooping_add_group4(struct mcast_snooping *ms, ovs_be32 ip4,
-   uint16_t vlan, void *port)
+ 

[ovs-dev] [PATCH v2] mcast-snooping: Store IGMP/MLD protocol version.

2023-11-16 Thread Mohammad Heib
Store the igmp/mld protocol version into the
mcast_group internally.

This can be used by ovs consumers to update
about the igmp/mld version of each group.

Signed-off-by: Mohammad Heib 
---
 lib/mcast-snooping.c | 16 +---
 lib/mcast-snooping.h |  9 ++---
 ofproto/ofproto-dpif-xlate.c |  6 --
 3 files changed, 19 insertions(+), 12 deletions(-)

diff --git a/lib/mcast-snooping.c b/lib/mcast-snooping.c
index 029ca2855..926daf9ac 100644
--- a/lib/mcast-snooping.c
+++ b/lib/mcast-snooping.c
@@ -389,7 +389,7 @@ mcast_snooping_prune_expired(struct mcast_snooping *ms,
 bool
 mcast_snooping_add_group(struct mcast_snooping *ms,
  const struct in6_addr *addr,
- uint16_t vlan, void *port)
+ uint16_t vlan, void *port, uint8_t grp_proto)
 OVS_REQ_WRLOCK(ms->rwlock)
 {
 bool learned;
@@ -415,6 +415,7 @@ mcast_snooping_add_group(struct mcast_snooping *ms,
 hmap_insert(>table, >hmap_node, hash);
 grp->addr = *addr;
 grp->vlan = vlan;
+grp->protocol_version = grp_proto;
 ovs_list_init(>bundle_lru);
 learned = true;
 ms->need_revalidate = true;
@@ -431,17 +432,17 @@ mcast_snooping_add_group(struct mcast_snooping *ms,
 
 bool
 mcast_snooping_add_group4(struct mcast_snooping *ms, ovs_be32 ip4,
- uint16_t vlan, void *port)
+ uint16_t vlan, void *port, uint8_t grp_proto)
 OVS_REQ_WRLOCK(ms->rwlock)
 {
 struct in6_addr addr = in6_addr_mapped_ipv4(ip4);
-return mcast_snooping_add_group(ms, , vlan, port);
+return mcast_snooping_add_group(ms, , vlan, port, grp_proto);
 }
 
 int
 mcast_snooping_add_report(struct mcast_snooping *ms,
   const struct dp_packet *p,
-  uint16_t vlan, void *port)
+  uint16_t vlan, void *port, uint8_t grp_proto)
 {
 ovs_be32 ip4;
 size_t offset;
@@ -478,7 +479,7 @@ mcast_snooping_add_report(struct mcast_snooping *ms,
 || record->type == IGMPV3_CHANGE_TO_INCLUDE_MODE)) {
 ret = mcast_snooping_leave_group4(ms, ip4, vlan, port);
 } else {
-ret = mcast_snooping_add_group4(ms, ip4, vlan, port);
+ret = mcast_snooping_add_group4(ms, ip4, vlan, port, grp_proto);
 }
 if (ret) {
 count++;
@@ -513,7 +514,7 @@ mcast_snooping_add_mld(struct mcast_snooping *ms,
 
 switch (mld->type) {
 case MLD_REPORT:
-ret = mcast_snooping_add_group(ms, addr, vlan, port);
+ret = mcast_snooping_add_group(ms, addr, vlan, port, MLD_REPORT);
 if (ret) {
 count++;
 }
@@ -545,7 +546,8 @@ mcast_snooping_add_mld(struct mcast_snooping *ms,
 || record->type == IGMPV3_CHANGE_TO_INCLUDE_MODE)) {
 ret = mcast_snooping_leave_group(ms, addr, vlan, port);
 } else {
-ret = mcast_snooping_add_group(ms, addr, vlan, port);
+ret = mcast_snooping_add_group(ms, addr, vlan, port,
+   MLD2_REPORT);
 }
 if (ret) {
 count++;
diff --git a/lib/mcast-snooping.h b/lib/mcast-snooping.h
index f120405da..6321b63ab 100644
--- a/lib/mcast-snooping.h
+++ b/lib/mcast-snooping.h
@@ -51,6 +51,9 @@ struct mcast_group {
 /* VLAN tag. */
 uint16_t vlan;
 
+/* Multicast group IPv6/IPv4 Protocol version IGMPv1,2,3 or MLDv1,2 */
+uint8_t protocol_version;
+
 /* Node in parent struct mcast_snooping group_lru. */
 struct ovs_list group_node OVS_GUARDED;
 
@@ -185,14 +188,14 @@ mcast_snooping_lookup4(const struct mcast_snooping *ms, 
ovs_be32 ip4,
 /* Learning. */
 bool mcast_snooping_add_group(struct mcast_snooping *ms,
   const struct in6_addr *addr,
-  uint16_t vlan, void *port)
+  uint16_t vlan, void *port, uint8_t grp_proto)
 OVS_REQ_WRLOCK(ms->rwlock);
 bool mcast_snooping_add_group4(struct mcast_snooping *ms, ovs_be32 ip4,
-   uint16_t vlan, void *port)
+   uint16_t vlan, void *port, uint8_t grp_proto)
 OVS_REQ_WRLOCK(ms->rwlock);
 int mcast_snooping_add_report(struct mcast_snooping *ms,
   const struct dp_packet *p,
-  uint16_t vlan, void *port)
+  uint16_t vlan, void *port, uint8_t grp_proto)
 OVS_REQ_WRLOCK(ms->rwlock);
 int mcast_snooping_add_mld(struct mcast_snooping *ms,
const struct dp_packet *p,
diff --git a/ofproto/ofproto-dpif-xlate.c b/ofproto/ofproto-dpif-xlate.c
index e24377330..26bd678cd 100644
--- a/ofproto/ofproto-dpif-xlate.c
+++ b/ofproto/ofproto-dpif-xlate.c
@@ -2781,7 +2781,8 @

[ovs-dev] [PATCH] mcast-snooping: store IGMP/MLD protocol version

2023-11-16 Thread Mohammad Heib
Store the igmp/mld protocol version into the
mcast_group internally.

This can be used by ovs consumers to update
about the igmp/mld version of each group.

Signed-off-by: Mohammad Heib 
---
 lib/mcast-snooping.c | 15 ---
 lib/mcast-snooping.h |  9 ++---
 ofproto/ofproto-dpif-xlate.c |  6 --
 3 files changed, 18 insertions(+), 12 deletions(-)

diff --git a/lib/mcast-snooping.c b/lib/mcast-snooping.c
index 029ca2855..185723861 100644
--- a/lib/mcast-snooping.c
+++ b/lib/mcast-snooping.c
@@ -389,7 +389,7 @@ mcast_snooping_prune_expired(struct mcast_snooping *ms,
 bool
 mcast_snooping_add_group(struct mcast_snooping *ms,
  const struct in6_addr *addr,
- uint16_t vlan, void *port)
+ uint16_t vlan, void *port, uint8_t grp_proto)
 OVS_REQ_WRLOCK(ms->rwlock)
 {
 bool learned;
@@ -415,6 +415,7 @@ mcast_snooping_add_group(struct mcast_snooping *ms,
 hmap_insert(>table, >hmap_node, hash);
 grp->addr = *addr;
 grp->vlan = vlan;
+grp->protocol_version = grp_proto;
 ovs_list_init(>bundle_lru);
 learned = true;
 ms->need_revalidate = true;
@@ -431,17 +432,17 @@ mcast_snooping_add_group(struct mcast_snooping *ms,
 
 bool
 mcast_snooping_add_group4(struct mcast_snooping *ms, ovs_be32 ip4,
- uint16_t vlan, void *port)
+ uint16_t vlan, void *port, uint8_t grp_proto)
 OVS_REQ_WRLOCK(ms->rwlock)
 {
 struct in6_addr addr = in6_addr_mapped_ipv4(ip4);
-return mcast_snooping_add_group(ms, , vlan, port);
+return mcast_snooping_add_group(ms, , vlan, port, grp_proto);
 }
 
 int
 mcast_snooping_add_report(struct mcast_snooping *ms,
   const struct dp_packet *p,
-  uint16_t vlan, void *port)
+  uint16_t vlan, void *port, uint8_t grp_proto)
 {
 ovs_be32 ip4;
 size_t offset;
@@ -478,7 +479,7 @@ mcast_snooping_add_report(struct mcast_snooping *ms,
 || record->type == IGMPV3_CHANGE_TO_INCLUDE_MODE)) {
 ret = mcast_snooping_leave_group4(ms, ip4, vlan, port);
 } else {
-ret = mcast_snooping_add_group4(ms, ip4, vlan, port);
+ret = mcast_snooping_add_group4(ms, ip4, vlan, port, grp_proto);
 }
 if (ret) {
 count++;
@@ -513,7 +514,7 @@ mcast_snooping_add_mld(struct mcast_snooping *ms,
 
 switch (mld->type) {
 case MLD_REPORT:
-ret = mcast_snooping_add_group(ms, addr, vlan, port);
+ret = mcast_snooping_add_group(ms, addr, vlan, port, MLD_REPORT);
 if (ret) {
 count++;
 }
@@ -545,7 +546,7 @@ mcast_snooping_add_mld(struct mcast_snooping *ms,
 || record->type == IGMPV3_CHANGE_TO_INCLUDE_MODE)) {
 ret = mcast_snooping_leave_group(ms, addr, vlan, port);
 } else {
-ret = mcast_snooping_add_group(ms, addr, vlan, port);
+ret = mcast_snooping_add_group(ms, addr, vlan, port, 
MLD2_REPORT);
 }
 if (ret) {
 count++;
diff --git a/lib/mcast-snooping.h b/lib/mcast-snooping.h
index f120405da..6321b63ab 100644
--- a/lib/mcast-snooping.h
+++ b/lib/mcast-snooping.h
@@ -51,6 +51,9 @@ struct mcast_group {
 /* VLAN tag. */
 uint16_t vlan;
 
+/* Multicast group IPv6/IPv4 Protocol version IGMPv1,2,3 or MLDv1,2 */
+uint8_t protocol_version;
+
 /* Node in parent struct mcast_snooping group_lru. */
 struct ovs_list group_node OVS_GUARDED;
 
@@ -185,14 +188,14 @@ mcast_snooping_lookup4(const struct mcast_snooping *ms, 
ovs_be32 ip4,
 /* Learning. */
 bool mcast_snooping_add_group(struct mcast_snooping *ms,
   const struct in6_addr *addr,
-  uint16_t vlan, void *port)
+  uint16_t vlan, void *port, uint8_t grp_proto)
 OVS_REQ_WRLOCK(ms->rwlock);
 bool mcast_snooping_add_group4(struct mcast_snooping *ms, ovs_be32 ip4,
-   uint16_t vlan, void *port)
+   uint16_t vlan, void *port, uint8_t grp_proto)
 OVS_REQ_WRLOCK(ms->rwlock);
 int mcast_snooping_add_report(struct mcast_snooping *ms,
   const struct dp_packet *p,
-  uint16_t vlan, void *port)
+  uint16_t vlan, void *port, uint8_t grp_proto)
 OVS_REQ_WRLOCK(ms->rwlock);
 int mcast_snooping_add_mld(struct mcast_snooping *ms,
const struct dp_packet *p,
diff --git a/ofproto/ofproto-dpif-xlate.c b/ofproto/ofproto-dpif-xlate.c
index e24377330..26bd678cd 100644
--- a/ofproto/ofproto-dpif-xlate.c
+++ b/ofproto/ofproto-dpif-xlate.c
@@ -2781,7 +2781,8 @@ update_mcast_snooping_table4__(const struct xla

[ovs-dev] [PATCH ovn v2] DNS: allow defining records that owned by OVN only

2023-11-13 Thread Mohammad Heib
Currently OVN allows users to create DNS records
and define domains within these records.

These domains can be associated with IPV4 or IPv6
or both, when the user creates a domain with both
IPv4 and IPv6 ovn will answer each query for this
domain immediately and everything works as expected.

But if the user only creates a domain with only IPv4
or IPv6 this will cause the DNS queries respond take
longer than the usual since OVN will forward query and
user will keep waiting for an answer until someone else
replies for this query or timeout occur.

The above behavior is a bit problematic if the user knows
that this domain is only configured in OVN we should not
forward queries for this domain to the outside.

This patch adds an option:ovn-owned for the DNS table
that can be set to "true" when creating a DNS.

When setting this option to "true" all the domains within
this table will be treated as local domains only,
and queries for domains within this table that don't have
an accurate IP will be refused immediately to save the time
of waiting for timeout.

Reported-at: https://bugzilla.redhat.com/show_bug.cgi?id=1946662
Signed-off-by: Mohammad Heib 
---
 NEWS |  4 +++
 controller/pinctrl.c | 43 -
 northd/northd.c  | 13 +
 ovn-nb.ovsschema |  9 --
 ovn-nb.xml   | 14 ++
 ovn-sb.ovsschema |  9 --
 ovn-sb.xml   |  6 
 tests/ovn.at | 65 
 8 files changed, 158 insertions(+), 5 deletions(-)

diff --git a/NEWS b/NEWS
index 30f6edb28..e10fb79dd 100644
--- a/NEWS
+++ b/NEWS
@@ -1,5 +1,9 @@
 Post v23.09.0
 -
+  - DNS now have an "options" column for configuration of extra options.
+  - A new DNS option "ovn-owned" has been added to allow defining domains
+that are owned only by ovn, queries for that domain will not be processed
+externally.
   - Disable OpenFlow inactivity probing between ovn-controller and OVS.
 OF connection is established over unix socket, which is a reliable
 connection method and doesn't require additional probing.
diff --git a/controller/pinctrl.c b/controller/pinctrl.c
index d88e951a6..cf48089b6 100644
--- a/controller/pinctrl.c
+++ b/controller/pinctrl.c
@@ -179,6 +179,7 @@ struct pinctrl {
 struct latch pinctrl_thread_exit;
 bool mac_binding_can_timestamp;
 bool fdb_can_timestamp;
+bool dns_supports_ovn_owned;
 };
 
 static struct pinctrl pinctrl;
@@ -2713,6 +2714,7 @@ struct dns_data {
 uint64_t *dps;
 size_t n_dps;
 struct smap records;
+struct smap options;
 bool delete;
 };
 
@@ -2741,6 +2743,7 @@ sync_dns_cache(const struct sbrec_dns_table *dns_table)
 if (!dns_data) {
 dns_data = xmalloc(sizeof *dns_data);
 smap_init(_data->records);
+smap_init(_data->options);
 shash_add(_cache, dns_id, dns_data);
 dns_data->n_dps = 0;
 dns_data->dps = NULL;
@@ -2755,6 +2758,12 @@ sync_dns_cache(const struct sbrec_dns_table *dns_table)
 smap_clone(_data->records, _dns->records);
 }
 
+if (pinctrl.dns_supports_ovn_owned
+&& !smap_equal(_data->options, _dns->options)) {
+smap_destroy(_data->options);
+smap_clone(_data->options, _dns->options);
+}
+
 dns_data->n_dps = sbrec_dns->n_datapaths;
 dns_data->dps = xcalloc(dns_data->n_dps, sizeof(uint64_t));
 for (size_t i = 0; i < sbrec_dns->n_datapaths; i++) {
@@ -2767,6 +2776,7 @@ sync_dns_cache(const struct sbrec_dns_table *dns_table)
 if (d->delete) {
 shash_delete(_cache, iter);
 smap_destroy(>records);
+smap_destroy(>options);
 free(d->dps);
 free(d);
 }
@@ -2781,6 +2791,7 @@ destroy_dns_cache(void)
 struct dns_data *d = iter->data;
 shash_delete(_cache, iter);
 smap_destroy(>records);
+smap_destroy(>options);
 free(d->dps);
 free(d);
 }
@@ -2854,6 +2865,8 @@ dns_build_ptr_answer(
 free(encoded);
 }
 
+#define DNS_RCODE_SERVER_REFUSE 0x5
+
 /* Called with in the pinctrl_handler thread context. */
 static void
 pinctrl_handle_dns_lookup(
@@ -2867,6 +2880,7 @@ pinctrl_handle_dns_lookup(
 enum ofputil_protocol proto = ofputil_protocol_from_ofp_version(version);
 struct dp_packet *pkt_out_ptr = NULL;
 uint32_t success = 0;
+bool send_refuse = false;
 
 /* Parse result field. */
 const struct mf_field *f;
@@ -2966,6 +2980,7 @@ pinctrl_handle_dns_lookup(
 
 uint64_t dp_key = ntohll(pin->flow_metadata.flow.metadata);
 const char *answer_data = NULL;
+bool ovn_owned = false;
 struct shash_node *iter;
 SHASH_FOR_EACH (iter, _cache) {
 struct dns_data *d = i

[ovs-dev] [PATCH ovn v2] controller: release container lport when releasing parent port

2023-11-06 Thread Mohammad Heib
Currently if the user sets the container parent_port:requested-chassis
option after the VIF/CIF is bonded to the chassis, this will migrate
the VIF/CIF flows to the new chassis but will still have the
container flows installed in the old chassis which can allow unwanted
tagged traffic to reach VMS/containers on the old chassis.

This patch will resolve the above issue by remove the CIF flows
from the old chassis and prevent the CIF from being bonded to a
chassis different from the parent port VIF binding chassis.

Rreported-at: https://bugzilla.redhat.com/show_bug.cgi?id=2220938
Signed-off-by: Mohammad Heib 
---
 controller/binding.c| 19 +++
 controller/physical.c   |  9 +++
 tests/ovn-controller.at | 53 +
 3 files changed, 81 insertions(+)

diff --git a/controller/binding.c b/controller/binding.c
index 8020d052f..0b64a1226 100644
--- a/controller/binding.c
+++ b/controller/binding.c
@@ -1600,6 +1600,22 @@ consider_vif_lport_(const struct sbrec_port_binding *pb,
 if_status_mgr_remove_ovn_installed(b_ctx_out->if_mgr,
b_lport->lbinding->iface->name,
_lport->lbinding->iface->header_.uuid);
+
+struct binding_lport *tmp_b_lport = b_lport;
+LIST_FOR_EACH (tmp_b_lport, list_node,
+  _b_lport->lbinding->binding_lports) {
+/* release children lports of type container if the primary
+ * binding lport cannot be bind to this chassis.
+ */
+if (tmp_b_lport->type == LP_CONTAINER) {
+if (!release_lport(tmp_b_lport->pb, b_ctx_in->chassis_rec,
+   !b_ctx_in->ovnsb_idl_txn,
+   b_ctx_out->tracked_dp_bindings,
+   b_ctx_out->if_mgr)) {
+return false;
+}
+}
+}
 }
 
 if (!lbinding_set || !can_bind) {
@@ -1734,6 +1750,9 @@ consider_container_lport(const struct sbrec_port_binding 
*pb,
 
 ovs_assert(parent_b_lport && parent_b_lport->pb);
 bool can_bind = lport_can_bind_on_this_chassis(b_ctx_in->chassis_rec, pb);
+/* cannot bind to this chassis if the parent_port cannot be bounded. */
+can_bind &= lport_can_bind_on_this_chassis(b_ctx_in->chassis_rec,
+   parent_b_lport->pb);
 
 return consider_vif_lport_(pb, can_bind, b_ctx_in, b_ctx_out,
container_b_lport);
diff --git a/controller/physical.c b/controller/physical.c
index 2338561ec..4e169e35f 100644
--- a/controller/physical.c
+++ b/controller/physical.c
@@ -1573,6 +1573,15 @@ consider_port_binding(struct ovsdb_idl_index 
*sbrec_port_binding_by_name,
 nested_container = true;
 parent_port = lport_lookup_by_name(
 sbrec_port_binding_by_name, binding->parent_port);
+
+if (parent_port
+&& !lport_can_bind_on_this_chassis(chassis, parent_port)) {
+/* Even though there is an ofport for this container
+ * parent port, it is requested on different chassis ignore
+ * this container port.
+ */
+return;
+}
 }
 } else if (!strcmp(binding->type, "localnet")
  || !strcmp(binding->type, "l2gateway")) {
diff --git a/tests/ovn-controller.at b/tests/ovn-controller.at
index e72438fbf..8a1904378 100644
--- a/tests/ovn-controller.at
+++ b/tests/ovn-controller.at
@@ -2700,3 +2700,56 @@ AT_CHECK([as hv1 ovs-ofctl dump-flows br-int table=40 | 
grep -q controller], [1]
 OVN_CLEANUP([hv1])
 AT_CLEANUP
 ])
+
+OVN_FOR_EACH_NORTHD([
+AT_SETUP([ovn-controller - cleanup VIF/CIF related flows/fields when updating 
requested-chassis])
+ovn_start
+
+net_add n1
+sim_add hv1
+ovs-vsctl add-br br-phys
+ovn_attach n1 br-phys 192.168.0.1
+check ovs-vsctl -- add-port br-int vif1 -- \
+set Interface vif1 external-ids:iface-id=lsp1 \
+ofport-request=8
+
+check ovn-nbctl ls-add lsw0
+
+check ovn-nbctl lsp-add lsw0 lsp1
+check ovn-nbctl lsp-add lsw0 sw0-port1.1 lsp1 7
+
+# wait for the VIF to be claimed to this chassis
+wait_row_count Chassis 1 name=hv1
+hv1_uuid=$(fetch_column Chassis _uuid name=hv1)
+wait_for_ports_up lsp1
+wait_for_ports_up sw0-port1.1
+wait_column "$hv1_uuid" Port_Binding chassis logical_port=lsp1
+wait_column "$hv1_uuid" Port_Binding chassis logical_port=sw0-port1.1
+
+# check that flows is installed
+OVS_WAIT_FOR_OUTPUT([as hv1 ovs-ofctl dump-flows br-int table=0 |grep 
priority=100 | grep -c in_port=8], [0],[dnl
+1
+])
+OVS_WAIT_FOR_OUTPUT([as hv1 ovs-ofctl dump-flows br-int table=0 |grep 
priority=150|grep dl_vlan=7| grep -c i

[ovs-dev] [PATCH ovn] DNS: allow defining records that owned by OVN only

2023-10-01 Thread Mohammad Heib
Currently OVN allows users to create DNS records
and define domains within these records.

These domains can be associated with IPV4 or IPv6
or both, when the user creates a domain with both
IPv4 and IPv6 ovn will answer each query for this
domain immediately and everything works as expected.

But if the user only creates a domain with only IPv4
or IPv6 this will cause the DNS queries respond take
longer than the usual since OVN will forward query and
user will keep waiting for an answer until someone else
replies for this query or timeout occur.

The above behavior is a bit problematic if the user knows
that this domain is only configured in OVN we should not
forward queries for this domain to the outside.

This patch adds an option:ovn-owned for the DNS table
that can be set to "true" when creating a DNS.

When setting this option to "true" all the domains within
this table will be treated as local domains only,
and queries for domains within this table that don't have
an accurate IP will be refused immediately to save the time
of waiting for timeout.

Reported-at: https://bugzilla.redhat.com/show_bug.cgi?id=1946662
Signed-off-by: Mohammad Heib 
---
 NEWS |  5 
 controller/pinctrl.c | 47 ++--
 northd/northd.c  | 11 
 ovn-nb.ovsschema |  9 --
 ovn-nb.xml   | 14 ++
 ovn-sb.ovsschema |  9 --
 ovn-sb.xml   |  6 
 tests/ovn.at | 65 
 8 files changed, 160 insertions(+), 6 deletions(-)

diff --git a/NEWS b/NEWS
index 425dfe0a8..465649430 100644
--- a/NEWS
+++ b/NEWS
@@ -1,5 +1,10 @@
 Post v23.09.0
 -
+  - DNS now have an "options" column for configuration of extra options.
+  - A new DNS option "ovn-owned" has been added to allow defining domains
+that are owned only by ovn, queries for that domain will not be processed
+externally.
+
 
 OVN v23.09.0 - 15 Sep 2023
 --
diff --git a/controller/pinctrl.c b/controller/pinctrl.c
index ff5a3444c..e1e558595 100644
--- a/controller/pinctrl.c
+++ b/controller/pinctrl.c
@@ -179,6 +179,7 @@ struct pinctrl {
 struct latch pinctrl_thread_exit;
 bool mac_binding_can_timestamp;
 bool fdb_can_timestamp;
+bool dns_can_ovn_owned;
 };
 
 static struct pinctrl pinctrl;
@@ -2709,6 +2710,7 @@ struct dns_data {
 uint64_t *dps;
 size_t n_dps;
 struct smap records;
+struct smap options;
 bool delete;
 };
 
@@ -2737,6 +2739,7 @@ sync_dns_cache(const struct sbrec_dns_table *dns_table)
 if (!dns_data) {
 dns_data = xmalloc(sizeof *dns_data);
 smap_init(_data->records);
+smap_init(_data->options);
 shash_add(_cache, dns_id, dns_data);
 dns_data->n_dps = 0;
 dns_data->dps = NULL;
@@ -2751,6 +2754,12 @@ sync_dns_cache(const struct sbrec_dns_table *dns_table)
 smap_clone(_data->records, _dns->records);
 }
 
+if (pinctrl.dns_can_ovn_owned
+&& !smap_equal(_data->options, _dns->options)) {
+smap_destroy(_data->options);
+smap_clone(_data->options, _dns->options);
+}
+
 dns_data->n_dps = sbrec_dns->n_datapaths;
 dns_data->dps = xcalloc(dns_data->n_dps, sizeof(uint64_t));
 for (size_t i = 0; i < sbrec_dns->n_datapaths; i++) {
@@ -2763,6 +2772,7 @@ sync_dns_cache(const struct sbrec_dns_table *dns_table)
 if (d->delete) {
 shash_delete(_cache, iter);
 smap_destroy(>records);
+smap_destroy(>options);
 free(d->dps);
 free(d);
 }
@@ -2777,6 +2787,7 @@ destroy_dns_cache(void)
 struct dns_data *d = iter->data;
 shash_delete(_cache, iter);
 smap_destroy(>records);
+smap_destroy(>options);
 free(d->dps);
 free(d);
 }
@@ -2850,6 +2861,8 @@ dns_build_ptr_answer(
 free(encoded);
 }
 
+#define DNS_RCODE_SERVER_REFUSE 0x5
+
 /* Called with in the pinctrl_handler thread context. */
 static void
 pinctrl_handle_dns_lookup(
@@ -2863,6 +2876,7 @@ pinctrl_handle_dns_lookup(
 enum ofputil_protocol proto = ofputil_protocol_from_ofp_version(version);
 struct dp_packet *pkt_out_ptr = NULL;
 uint32_t success = 0;
+bool send_query_rejection = false;
 
 /* Parse result field. */
 const struct mf_field *f;
@@ -2962,6 +2976,7 @@ pinctrl_handle_dns_lookup(
 
 uint64_t dp_key = ntohll(pin->flow_metadata.flow.metadata);
 const char *answer_data = NULL;
+bool ovn_owned = false;
 struct shash_node *iter;
 SHASH_FOR_EACH (iter, _cache) {
 struct dns_data *d = iter->data;
@@ -2974,6 +2989,7 @@ pinctrl_handle_dns_lookup(
 answer_data = smap_get(>records, query_name_lower);
 fre

[ovs-dev] DNS: allow defining records that owned by OVN only

2023-10-01 Thread Mohammad Heib
Currently OVN allows users to create DNS records
and define domains within these records.

These domains can be associated with IPV4 or IPv6
or both, when the user creates a domain with both
IPv4 and IPv6 ovn will answer each query for this
domain immediately and everything works as expected.

But if the user only creates a domain with only IPv4
or IPv6 this will cause the DNS queries respond take
longer than the usual since OVN will forward query and
user will keep waiting for an answer until someone else
replies for this query or timeout occur.

The above behavior is a bit problematic if the user knows
that this domain is only configured in OVN we should not
forward queries for this domain to the outside.

This patch adds an option:ovn-owned for the DNS table
that can be set to "true" when creating a DNS.

When setting this option to "true" all the domains within
this table will be treated as local domains only,
and queries for domains within this table that don't have
an accurate IP will be refused immediately to save the time
of waiting for timeout.

Reported-at: https://bugzilla.redhat.com/show_bug.cgi?id=1946662
Signed-off-by: Mohammad Heib 
---
 NEWS |  5 
 controller/pinctrl.c | 47 ++--
 northd/northd.c  | 11 
 ovn-nb.ovsschema |  9 --
 ovn-nb.xml   | 14 ++
 ovn-sb.ovsschema |  9 --
 ovn-sb.xml   |  6 
 tests/ovn.at | 65 
 8 files changed, 160 insertions(+), 6 deletions(-)

diff --git a/NEWS b/NEWS
index 425dfe0a8..465649430 100644
--- a/NEWS
+++ b/NEWS
@@ -1,5 +1,10 @@
 Post v23.09.0
 -
+  - DNS now have an "options" column for configuration of extra options.
+  - A new DNS option "ovn-owned" has been added to allow defining domains
+that are owned only by ovn, queries for that domain will not be processed
+externally.
+
 
 OVN v23.09.0 - 15 Sep 2023
 --
diff --git a/controller/pinctrl.c b/controller/pinctrl.c
index ff5a3444c..e1e558595 100644
--- a/controller/pinctrl.c
+++ b/controller/pinctrl.c
@@ -179,6 +179,7 @@ struct pinctrl {
 struct latch pinctrl_thread_exit;
 bool mac_binding_can_timestamp;
 bool fdb_can_timestamp;
+bool dns_can_ovn_owned;
 };
 
 static struct pinctrl pinctrl;
@@ -2709,6 +2710,7 @@ struct dns_data {
 uint64_t *dps;
 size_t n_dps;
 struct smap records;
+struct smap options;
 bool delete;
 };
 
@@ -2737,6 +2739,7 @@ sync_dns_cache(const struct sbrec_dns_table *dns_table)
 if (!dns_data) {
 dns_data = xmalloc(sizeof *dns_data);
 smap_init(_data->records);
+smap_init(_data->options);
 shash_add(_cache, dns_id, dns_data);
 dns_data->n_dps = 0;
 dns_data->dps = NULL;
@@ -2751,6 +2754,12 @@ sync_dns_cache(const struct sbrec_dns_table *dns_table)
 smap_clone(_data->records, _dns->records);
 }
 
+if (pinctrl.dns_can_ovn_owned
+&& !smap_equal(_data->options, _dns->options)) {
+smap_destroy(_data->options);
+smap_clone(_data->options, _dns->options);
+}
+
 dns_data->n_dps = sbrec_dns->n_datapaths;
 dns_data->dps = xcalloc(dns_data->n_dps, sizeof(uint64_t));
 for (size_t i = 0; i < sbrec_dns->n_datapaths; i++) {
@@ -2763,6 +2772,7 @@ sync_dns_cache(const struct sbrec_dns_table *dns_table)
 if (d->delete) {
 shash_delete(_cache, iter);
 smap_destroy(>records);
+smap_destroy(>options);
 free(d->dps);
 free(d);
 }
@@ -2777,6 +2787,7 @@ destroy_dns_cache(void)
 struct dns_data *d = iter->data;
 shash_delete(_cache, iter);
 smap_destroy(>records);
+smap_destroy(>options);
 free(d->dps);
 free(d);
 }
@@ -2850,6 +2861,8 @@ dns_build_ptr_answer(
 free(encoded);
 }
 
+#define DNS_RCODE_SERVER_REFUSE 0x5
+
 /* Called with in the pinctrl_handler thread context. */
 static void
 pinctrl_handle_dns_lookup(
@@ -2863,6 +2876,7 @@ pinctrl_handle_dns_lookup(
 enum ofputil_protocol proto = ofputil_protocol_from_ofp_version(version);
 struct dp_packet *pkt_out_ptr = NULL;
 uint32_t success = 0;
+bool send_query_rejection = false;
 
 /* Parse result field. */
 const struct mf_field *f;
@@ -2962,6 +2976,7 @@ pinctrl_handle_dns_lookup(
 
 uint64_t dp_key = ntohll(pin->flow_metadata.flow.metadata);
 const char *answer_data = NULL;
+bool ovn_owned = false;
 struct shash_node *iter;
 SHASH_FOR_EACH (iter, _cache) {
 struct dns_data *d = iter->data;
@@ -2974,6 +2989,7 @@ pinctrl_handle_dns_lookup(
 answer_data = smap_get(>records, query_name_lower);
 fre

[ovs-dev] [PATCH ovn] controller: release container lport when releasing parent port

2023-09-27 Thread Mohammad Heib
Currently if the user sets the container parent_port:requested-chassis
option after the VIF/CIF is bonded to the chassis, this will migrate
the VIF/CIF flows to the new chassis but will still have the
container flows installed in the old chassis which can allow unwanted
tagged traffic to reach VMS/containers on the old chassis.

This patch will resolve the above issue by remove the CIF flows
from the old chassis and prevent the CIF from being bonded to a
chassis different from the parent port VIF binding chassis.

Rreported-at: https://bugzilla.redhat.com/show_bug.cgi?id=2220938
Signed-off-by: Mohammad Heib 
---
 controller/binding.c| 18 ++
 controller/physical.c   |  9 +++
 tests/ovn-controller.at | 55 +
 3 files changed, 82 insertions(+)

diff --git a/controller/binding.c b/controller/binding.c
index fd08aaafa..2e58fb0cd 100644
--- a/controller/binding.c
+++ b/controller/binding.c
@@ -1599,6 +1599,21 @@ consider_vif_lport_(const struct sbrec_port_binding *pb,
 if_status_mgr_remove_ovn_installed(b_ctx_out->if_mgr,
b_lport->lbinding->iface->name,
_lport->lbinding->iface->header_.uuid);
+
+LIST_FOR_EACH (b_lport, list_node,
+  _lport->lbinding->binding_lports) {
+/* release children lports of type container if the primary
+ * binding lport cannot be bind to this chassis.
+ */
+if (b_lport->type == LP_CONTAINER) {
+if (!release_lport(b_lport->pb, b_ctx_in->chassis_rec,
+   !b_ctx_in->ovnsb_idl_txn,
+   b_ctx_out->tracked_dp_bindings,
+   b_ctx_out->if_mgr)) {
+return false;
+}
+}
+}
 }
 
 if (!lbinding_set || !can_bind) {
@@ -1733,6 +1748,9 @@ consider_container_lport(const struct sbrec_port_binding 
*pb,
 
 ovs_assert(parent_b_lport && parent_b_lport->pb);
 bool can_bind = lport_can_bind_on_this_chassis(b_ctx_in->chassis_rec, pb);
+/* cannot bind to this chassis if the parent_port cannot be bounded. */
+can_bind &= lport_can_bind_on_this_chassis(b_ctx_in->chassis_rec,
+   parent_b_lport->pb);
 
 return consider_vif_lport_(pb, can_bind, b_ctx_in, b_ctx_out,
container_b_lport);
diff --git a/controller/physical.c b/controller/physical.c
index 75257bc85..5a5824f39 100644
--- a/controller/physical.c
+++ b/controller/physical.c
@@ -1573,6 +1573,15 @@ consider_port_binding(struct ovsdb_idl_index 
*sbrec_port_binding_by_name,
 nested_container = true;
 parent_port = lport_lookup_by_name(
 sbrec_port_binding_by_name, binding->parent_port);
+
+if (parent_port
+&& !lport_can_bind_on_this_chassis(chassis, parent_port)) {
+/* Even though there is an ofport for this container
+ * parent port, it is requested on different chassis ignore
+ * this container port.
+ */
+return;
+}
 }
 } else if (!strcmp(binding->type, "localnet")
  || !strcmp(binding->type, "l2gateway")) {
diff --git a/tests/ovn-controller.at b/tests/ovn-controller.at
index 4212d601a..65c3aa84b 100644
--- a/tests/ovn-controller.at
+++ b/tests/ovn-controller.at
@@ -2651,3 +2651,58 @@ OVS_WAIT_FOR_OUTPUT([as hv1 ovs-ofctl dump-flows br-int 
table=0 | grep -c in_por
 OVN_CLEANUP([hv1])
 AT_CLEANUP
 ])
+
+OVN_FOR_EACH_NORTHD([
+AT_SETUP([ovn-controller - cleanup VIF/CIF related flows/fields when updating 
requested-chassis])
+ovn_start
+
+net_add n1
+sim_add hv1
+ovs-vsctl add-br br-phys
+ovn_attach n1 br-phys 192.168.0.1
+check ovs-vsctl -- add-port br-int vif1 -- \
+set Interface vif1 external-ids:iface-id=lsp1 \
+ofport-request=8
+
+check ovn-nbctl ls-add lsw0
+
+check ovn-nbctl lsp-add lsw0 lsp1
+check ovn-nbctl lsp-set-addresses lsp1 "f0:00:00:00:00:01 172.16.0.101"
+check ovn-nbctl lsp-add lsw0 sw0-port1.1 lsp1 7
+check ovn-nbctl lsp-set-addresses sw0-port1.1 "f0:00:00:01:02:07 192.168.2.2"
+
+# wait for the VIF to be claimed to this chassis
+wait_row_count Chassis 1 name=hv1
+hv1_uuid=$(fetch_column Chassis _uuid name=hv1)
+wait_for_ports_up lsp1
+wait_for_ports_up sw0-port1.1
+wait_column "$hv1_uuid" Port_Binding chassis logical_port=lsp1
+wait_column "$hv1_uuid" Port_Binding chassis logical_port=sw0-port1.1
+
+# check that flows is installed
+OVS_WAIT_FOR_OUTPUT([as hv1 ovs-ofctl dump-flows br-int table=0 |grep 
priority=100 | grep -c in_port=8], [0],[dnl
+1
+])
+OVS_WAIT_FOR_O

[ovs-dev] [PATCH ovn] pinctrl: DNS refuse inapplicable AAAA queries

2023-09-06 Thread Mohammad Heib
Currently ovn ignores DNS  queries that has
record in the DNS tables but no ipv6 associated
with this record, this will incress the DNS processing
time for the custmer since they will keep waiting for
reply or a timeout.

To improve the DNS processing time this patch will immediately
send a DNS reply with DNS RCODE flag set to 0x5 (server refuses
to perform the specified operation) and no DNS answers.

Reported-at: https://issues.redhat.com/browse/FD-1211
Signed-off-by: Mohammad Heib 
---
 controller/pinctrl.c | 28 +---
 tests/ovn.at | 32 
 2 files changed, 57 insertions(+), 3 deletions(-)

diff --git a/controller/pinctrl.c b/controller/pinctrl.c
index 1884e9f1b..3212900c5 100644
--- a/controller/pinctrl.c
+++ b/controller/pinctrl.c
@@ -2815,6 +2815,7 @@ pinctrl_handle_dns_lookup(
 enum ofputil_protocol proto = ofputil_protocol_from_ofp_version(version);
 struct dp_packet *pkt_out_ptr = NULL;
 uint32_t success = 0;
+bool send__query_rejection = false;
 
 /* Parse result field. */
 const struct mf_field *f;
@@ -2972,6 +2973,18 @@ pinctrl_handle_dns_lookup(
 ancount++;
 }
 }
+
+/* DNS is configured with a record for this domain with
+ * an IPv4 only, so instead of ignoring this  query,
+ * we can reply with  RCODE = 5 (server refuses) and that
+ * will speed up the DNS process by not letting the customer
+ * wait for a timeout.
+ */
+if (query_type == DNS_QUERY_TYPE_ && !ancount) {
+ancount = 1;
+send__query_rejection = true;
+}
+
 destroy_lport_addresses(_addrs);
 }
 
@@ -3009,15 +3022,24 @@ pinctrl_handle_dns_lookup(
 out_dns_header->lo_flag |= 0x80;
 
 /* Set the answer RRs. */
-out_dns_header->ancount = htons(ancount);
+if (!send__query_rejection) {
+out_dns_header->ancount = htons(ancount);
+} else {
+/* set RCODE = 5 (server refuses). */
+out_dns_header->ancount = 0;
+out_dns_header->hi_flag |= 0x5;
+ofpbuf_uninit(_answer);
+}
 out_dns_header->arcount = 0;
 
 /* Copy the Query section. */
 dp_packet_put(_out, dp_packet_data(pkt_in), dp_packet_size(pkt_in));
 
 /* Copy the answer sections. */
-dp_packet_put(_out, dns_answer.data, dns_answer.size);
-ofpbuf_uninit(_answer);
+if (!send__query_rejection) {
+dp_packet_put(_out, dns_answer.data, dns_answer.size);
+ofpbuf_uninit(_answer);
+}
 
 out_udp->udp_len = htons(new_l4_size);
 out_udp->udp_csum = 0;
diff --git a/tests/ovn.at b/tests/ovn.at
index c6c5f920f..7b90a991d 100644
--- a/tests/ovn.at
+++ b/tests/ovn.at
@@ -11290,6 +11290,38 @@ reset_pcap_file hv1-vif2 hv1/vif2
 rm -f 1.expected
 rm -f 2.expected
 
+# send  query for a server known domain that don't have
+# any IPV6 address associated with this domain, and expected
+# server refused DNS reply to save the sender time of waiting for timeout.
+AS_BOX([Test IPv6 ( records) NO timeout.])
+# Add back the DNS options for ls1-lp1 without ipv6.
+ovn-nbctl --wait=hv remove DNS $DNS1 records vm1.ovn.org
+ovn-nbctl --wait=hv set DNS $DNS1 records:vm1.ovn.org="10.0.0.4"
+ovn-sbctl list DNS > dns4
+AT_CAPTURE_FILE([dns4])
+ovn-sbctl dump-flows > sbflows4
+AT_CAPTURE_FILE([sbflows4])
+
+set_dns_params vm1_ipv6_only
+src_ip=`ip_to_hex 10 0 0 6`
+dst_ip=`ip_to_hex 10 0 0 1`
+dns_reply=1
+test_dns 2 f002 f0f0 $src_ip $dst_ip $dns_reply $dns_req_data 
$dns_resp_data
+
+# NXT_RESUMEs should be 5.
+OVS_WAIT_UNTIL([test 13 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
+
+$PYTHON "$ovs_srcdir/utilities/ovs-pcap.in" hv1/vif2-tx.pcap > 2.packets
+# dns hdr with server refuse RCODE
+echo "01028125"  > expout
+#only check for the DNS HDR flags since we are not getting any DNS answer
+AT_CHECK([cat 2.packets | cut -c -92 | cut -c 85-], [0], [expout])
+
+reset_pcap_file hv1-vif1 hv1/vif1
+reset_pcap_file hv1-vif2 hv1/vif2
+rm -f 1.expected
+rm -f 2.expected
+
 OVN_CLEANUP([hv1])
 
 AT_CLEANUP
-- 
2.34.3

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


Re: [ovs-dev] [PATCH ovn] binding: handle ovs ofport update

2023-07-31 Thread Mohammad Heib

Hi Mark,

thank you for reviewing my patch is submitted v2 addressing your comments.

On 7/28/23 23:16, Mark Michelson wrote:

Hi Mohammad,

The actual code change looks good, but I have some other minor 
comments to address. See inline below.


On 7/26/23 12:12, Mohammad Heib wrote:

Currently when ovs interface ofport is updated
after setting external_ids:iface_id, the ovn-controller
will see this change but will not do much if it handles
this change incrementally.

This behavior leads to a mismatch between the ovs openflow
flows in table=0 (inaccurate in_port) and the ofport number
that the packet was received at which will lead to packets
drop in table=0.

This patch will resolve the above issue by triggering
flows recompute during the I-P processing only if the
affected port are associated with lport and has flows
that need to be updated.

Reported-at: https://issues.redhat.com/browse/FD-3063
Signed-off-by: Mohammad Heib 
---
  controller/binding.c    | 35 +++
  tests/ovn-controller.at | 39 +++
  2 files changed, 74 insertions(+)

diff --git a/controller/binding.c b/controller/binding.c
index 9aa3fc6c4..d28548d93 100644
--- a/controller/binding.c
+++ b/controller/binding.c
@@ -1514,6 +1514,35 @@ release_lport(const struct sbrec_port_binding 
*pb,

  return true;
  }
  +/*
+ * This function will update the tracked_dp_bindings
+ * whenever an ofport on a specific ovs port.


s/specific ovs port/specific ovs port changes/


+ * This update will trigger flow recomputation during
+ * the incremental processing run which updates the local
+ * flows in_port filed.
+ *
+ * This function will trigger flow recomputation only for
+ * affected local_bindings that have port_binding associated
+ * with it, otherwise, no flows are installed and we don't
+ * have to update any in_port field.
+ */
+static void
+handle_ovs_ofport_update(const char *iface_id,
+ struct binding_ctx_out *b_ctx_out)
+{
+    struct shash *local_bindings = _ctx_out->lbinding_data->bindings;
+    struct local_binding *lbinding = local_binding_find(local_bindings,
+ iface_id);
+    struct binding_lport *b_lport =
+    local_binding_get_primary_or_localport_lport(lbinding);
+
+    if (b_lport) {
+    tracked_datapath_lport_add(b_lport->pb, 
TRACKED_RESOURCE_UPDATED,

+ b_ctx_out->tracked_dp_bindings);
+    b_ctx_out->local_lports_changed = true;
+    }
+}


I think this logic should move into consider_iface_claim() in 
binding.c. It is called for all relevant OVS interfaces, and that 
function also retrieves the local_binding and binding_lport.


In addition to saving a bit of computation, putting this change there 
would also prevent a potential crash, since it is possible that 
b_lport->pb may be NULL. We have a NULL check already in 
consider_iface_claim(), so you could insert this new code below that 
NULL check.



+
  static bool
  is_lbinding_set(struct local_binding *lbinding)
  {
@@ -2681,6 +2710,12 @@ binding_handle_ovs_interface_changes(struct 
binding_ctx_in *b_ctx_in,

  if (!handled) {
  break;
  }
+
+    if (!b_ctx_out->local_lports_changed
+ && ovsrec_interface_is_updated(iface_rec,
+ OVSREC_INTERFACE_COL_OFPORT)) {
+    handle_ovs_ofport_update(iface_id, b_ctx_out);
+    }
  }
  }
  diff --git a/tests/ovn-controller.at b/tests/ovn-controller.at
index 28c13234c..1461cade6 100644
--- a/tests/ovn-controller.at
+++ b/tests/ovn-controller.at
@@ -2608,3 +2608,42 @@ AT_CHECK([ovn-sbctl get chassis $chassis_id 
other_config:unsupported], [1], [ign

  OVN_CLEANUP([hv1])
  AT_CLEANUP
  ])
+
+OVN_FOR_EACH_NORTHD([
+AT_SETUP([ovn-controller - ovs iface change ofport])
+AT_KEYWORDS([ovn])
+ovn_start
+
+net_add n1
+
+sim_add hv1
+as hv1
+ovs-vsctl add-br br-phys
+ovn_attach n1 br-phys 192.168.0.1
+ovs-vsctl -- add-port br-int hv1-vif1 -- \
+    set interface hv1-vif1 external-ids:iface-id=sw0-p1 \
+    options:tx_pcap=hv1/vif1-tx.pcap \
+    options:rxq_pcap=hv1/vif1-rx.pcap \
+    ofport-request=1
+
+
+ovn-nbctl ls-add sw0
+
+check ovn-nbctl lsp-add sw0 sw0-p1
+check ovn-nbctl lsp-set-addresses sw0-p1 "50:54:00:00:00:03 10.0.0.3 
1000::3"

+
+wait_for_ports_up
+ovn-nbctl --wait=hv sync
+
+OVS_WAIT_UNTIL([test 1 = `as hv1 ovs-ofctl dump-flows br-int table=0 
| grep priority=100 | grep in_port=1 | grep "resubmit(,8)" | grep -c 
n_packets=0`])


A couple of things:
* Do we need to grep for the priority, the resubmit action, and 
"n_packets=0" ? Isn't it enough to just grep for in_port=1 in table 0?
* While this syntax works fine, there is an OVS_WAIT_FOR_OUTPUT macro 
that is more commonly used for this type of test.


OVS_WAIT_FOR_OUTPUT([as hv1 ovs-ofctl dump-flows br-int table=0 | grep 
-c in_port=1], [0],[dnl

1
]


+
+# update the ovs interface ofport from 1 to 24
+chec

[ovs-dev] [PATCH ovn v2] binding: handle ovs ofport update

2023-07-31 Thread Mohammad Heib
Currently when ovs interface ofport is updated
after setting external_ids:iface_id, the ovn-controller
will see this change but will not do much if it handles
this change incrementally.

This behavior leads to a mismatch between the ovs openflow
flows in table=0 (inaccurate in_port) and the ofport number
that the packet was received at which will lead to packets
drop in table=0.

This patch will resolve the above issue by triggering
flows recompute during the I-P processing only if the
affected port are associated with lport and has flows
that need to be updated.

Reported-at: https://issues.redhat.com/browse/FD-3063
Signed-off-by: Mohammad Heib 
---
 controller/binding.c| 15 ++
 tests/ovn-controller.at | 45 +
 2 files changed, 60 insertions(+)

diff --git a/controller/binding.c b/controller/binding.c
index 9aa3fc6c4..cc4c2b0bb 100644
--- a/controller/binding.c
+++ b/controller/binding.c
@@ -2360,6 +2360,21 @@ consider_iface_claim(const struct ovsrec_interface 
*iface_rec,
 /* Get the (updated) b_lport again for the lbinding. */
 b_lport = local_binding_get_primary_lport(lbinding);
 
+/*
+ * Update the tracked_dp_bindings whenever an ofport
+ * on a specific ovs port changes.
+ * This update will trigger flow recomputation during
+ * the incremental processing run which updates the local
+ * flows in_port filed.
+ */
+if (b_lport && ovsrec_interface_is_updated(iface_rec,
+OVSREC_INTERFACE_COL_OFPORT)) {
+tracked_datapath_lport_add(b_lport->pb, TRACKED_RESOURCE_UPDATED,
+   b_ctx_out->tracked_dp_bindings);
+b_ctx_out->local_lports_changed = true;
+}
+
+
 /* Update the child local_binding's iface (if any children) and try to
  *  claim the container lbindings. */
 LIST_FOR_EACH (b_lport, list_node, >binding_lports) {
diff --git a/tests/ovn-controller.at b/tests/ovn-controller.at
index e1b6491b3..f2216d245 100644
--- a/tests/ovn-controller.at
+++ b/tests/ovn-controller.at
@@ -2606,3 +2606,48 @@ AT_CHECK([ovn-sbctl get chassis $chassis_id 
other_config:unsupported], [1], [ign
 OVN_CLEANUP([hv1])
 AT_CLEANUP
 ])
+
+OVN_FOR_EACH_NORTHD([
+AT_SETUP([ovn-controller - ovs iface change ofport])
+AT_KEYWORDS([ovn])
+ovn_start
+
+net_add n1
+
+sim_add hv1
+as hv1
+ovs-vsctl add-br br-phys
+ovn_attach n1 br-phys 192.168.0.1
+ovs-vsctl -- add-port br-int hv1-vif1 -- \
+set interface hv1-vif1 external-ids:iface-id=sw0-p1 \
+options:tx_pcap=hv1/vif1-tx.pcap \
+options:rxq_pcap=hv1/vif1-rx.pcap \
+ofport-request=1
+
+
+ovn-nbctl ls-add sw0
+
+check ovn-nbctl lsp-add sw0 sw0-p1
+check ovn-nbctl lsp-set-addresses sw0-p1 "50:54:00:00:00:03 10.0.0.3 1000::3"
+
+wait_for_ports_up
+ovn-nbctl --wait=hv sync
+
+OVS_WAIT_FOR_OUTPUT([as hv1 ovs-ofctl dump-flows br-int table=0 | grep -c 
in_port=1], [0],[dnl
+1
+])
+
+# update the ovs interface ofport from 1 to 24
+check as hv1 ovs-vsctl set Interface hv1-vif1 ofport-request=24
+OVS_WAIT_UNTIL([test x`as hv1 ovs-vsctl get Interface hv1-vif1 ofport` = x24])
+
+OVS_WAIT_FOR_OUTPUT([as hv1 ovs-ofctl dump-flows br-int table=0 | grep -c 
in_port=24], [0],[dnl
+1
+])
+OVS_WAIT_FOR_OUTPUT([as hv1 ovs-ofctl dump-flows br-int table=0 | grep -c 
in_port=1], [1],[dnl
+0
+])
+
+OVN_CLEANUP([hv1])
+AT_CLEANUP
+])
-- 
2.34.3

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


[ovs-dev] [PATCH ovn] binding: handle ovs ofport update

2023-07-26 Thread Mohammad Heib
Currently when ovs interface ofport is updated
after setting external_ids:iface_id, the ovn-controller
will see this change but will not do much if it handles
this change incrementally.

This behavior leads to a mismatch between the ovs openflow
flows in table=0 (inaccurate in_port) and the ofport number
that the packet was received at which will lead to packets
drop in table=0.

This patch will resolve the above issue by triggering
flows recompute during the I-P processing only if the
affected port are associated with lport and has flows
that need to be updated.

Reported-at: https://issues.redhat.com/browse/FD-3063
Signed-off-by: Mohammad Heib 
---
 controller/binding.c| 35 +++
 tests/ovn-controller.at | 39 +++
 2 files changed, 74 insertions(+)

diff --git a/controller/binding.c b/controller/binding.c
index 9aa3fc6c4..d28548d93 100644
--- a/controller/binding.c
+++ b/controller/binding.c
@@ -1514,6 +1514,35 @@ release_lport(const struct sbrec_port_binding *pb,
 return true;
 }
 
+/*
+ * This function will update the tracked_dp_bindings
+ * whenever an ofport on a specific ovs port.
+ * This update will trigger flow recomputation during
+ * the incremental processing run which updates the local
+ * flows in_port filed.
+ *
+ * This function will trigger flow recomputation only for
+ * affected local_bindings that have port_binding associated
+ * with it, otherwise, no flows are installed and we don't
+ * have to update any in_port field.
+ */
+static void
+handle_ovs_ofport_update(const char *iface_id,
+ struct binding_ctx_out *b_ctx_out)
+{
+struct shash *local_bindings = _ctx_out->lbinding_data->bindings;
+struct local_binding *lbinding = local_binding_find(local_bindings,
+iface_id);
+struct binding_lport *b_lport =
+local_binding_get_primary_or_localport_lport(lbinding);
+
+if (b_lport) {
+tracked_datapath_lport_add(b_lport->pb, TRACKED_RESOURCE_UPDATED,
+   b_ctx_out->tracked_dp_bindings);
+b_ctx_out->local_lports_changed = true;
+}
+}
+
 static bool
 is_lbinding_set(struct local_binding *lbinding)
 {
@@ -2681,6 +2710,12 @@ binding_handle_ovs_interface_changes(struct 
binding_ctx_in *b_ctx_in,
 if (!handled) {
 break;
 }
+
+if (!b_ctx_out->local_lports_changed
+ && ovsrec_interface_is_updated(iface_rec,
+OVSREC_INTERFACE_COL_OFPORT)) {
+handle_ovs_ofport_update(iface_id, b_ctx_out);
+}
 }
 }
 
diff --git a/tests/ovn-controller.at b/tests/ovn-controller.at
index 28c13234c..1461cade6 100644
--- a/tests/ovn-controller.at
+++ b/tests/ovn-controller.at
@@ -2608,3 +2608,42 @@ AT_CHECK([ovn-sbctl get chassis $chassis_id 
other_config:unsupported], [1], [ign
 OVN_CLEANUP([hv1])
 AT_CLEANUP
 ])
+
+OVN_FOR_EACH_NORTHD([
+AT_SETUP([ovn-controller - ovs iface change ofport])
+AT_KEYWORDS([ovn])
+ovn_start
+
+net_add n1
+
+sim_add hv1
+as hv1
+ovs-vsctl add-br br-phys
+ovn_attach n1 br-phys 192.168.0.1
+ovs-vsctl -- add-port br-int hv1-vif1 -- \
+set interface hv1-vif1 external-ids:iface-id=sw0-p1 \
+options:tx_pcap=hv1/vif1-tx.pcap \
+options:rxq_pcap=hv1/vif1-rx.pcap \
+ofport-request=1
+
+
+ovn-nbctl ls-add sw0
+
+check ovn-nbctl lsp-add sw0 sw0-p1
+check ovn-nbctl lsp-set-addresses sw0-p1 "50:54:00:00:00:03 10.0.0.3 1000::3"
+
+wait_for_ports_up
+ovn-nbctl --wait=hv sync
+
+OVS_WAIT_UNTIL([test 1 = `as hv1 ovs-ofctl dump-flows br-int table=0 | grep 
priority=100 | grep in_port=1 | grep "resubmit(,8)" | grep -c n_packets=0`])
+
+# update the ovs interface ofport from 1 to 24
+check as hv1 ovs-vsctl set Interface hv1-vif1 ofport-request=24
+OVS_WAIT_UNTIL([test x`as hv1 ovs-vsctl get Interface hv1-vif1 ofport` = x24])
+
+OVS_WAIT_UNTIL([test 1 = `as hv1 ovs-ofctl dump-flows br-int table=0 | grep 
priority=100 | grep in_port=24 | grep "resubmit(,8)" | grep -c n_packets=0`])
+OVS_WAIT_UNTIL([test 0 = `as hv1 ovs-ofctl dump-flows br-int table=0 | grep 
priority=100 | grep in_port=1 | grep "resubmit(,8)" | grep -c n_packets=0`])
+
+OVN_CLEANUP([hv1])
+AT_CLEANUP
+])
-- 
2.34.3

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


Re: [ovs-dev] [PATCH ovn v3] binding.c: update ld->peers when lsp type updated

2022-08-18 Thread Mohammad Heib
Hi Mark,
Thank you for reviewing the patch.
actually, the test here is less interested in the type update but more in
the LSP deletion from the ld->peer_ports list
i don't have a way to see if the ld->n_peer_ports updated properly from the
tests units  when we change the port type, but i know that
if something wrong happens in the ovn-controller and ld->peer_ports keeps
pointing to the deleted LSP( which is what this patch
comes to fix ) the command* "check ovn-nbctl lrp-del lrp"* will cause some
invalid memory access and that will lead to a core dump in the
ovn-controller
and then the test case will fail with dump in the ovn-controller logs.
i know it is a bad way to test it like that but as i mentioned i don't have
a way to see the content of ld->peer_ports from the test :(.

see comments in the tests below.

On Thu, Aug 18, 2022 at 9:18 PM Mark Michelson  wrote:

> Hi Mohammad. The code changes look good, but I'm a bit confused about
> what the test case is intending to prove. It updates the type of the
> LSP, but there is no check to ensure that the change was successful, as
> far as I can tell.
>


>
> On 8/16/22 06:56, Mohammad Heib wrote:
> > The local_datapath->peer_ports list contains peers pointers
> > to lsp<-->lrp ports that are supposed to be router end ports,
> > those pointers are added and deleted to the  local_datapath->peer_ports
> > when logical switch port of type router are added or deleted from the
> database.
> >
> > The deletion and creation of those ports are handled very well when the
> LSP type
> > is a router, but if in any case, the user has changed the LSP type from
> router
> > port to any other LSP type the ld->peer_ports will keep pointing to this
> port
> > and if it was deleted it will keep pointing to invalid memory regions
> and that
> > could lead to invalid memory access in the ovn-controller.
> >
> > To solve the above issue this patch will update the
> local_dataoath->peer_ports
> > whenever a lport is updated.
> >
> > Reported-at: https://bugzilla.redhat.com/show_bug.cgi?id=2077078
> > Co-authored-by: Xavier Simonart 
> > Signed-off-by: Mohammad Heib 
> > Signed-off-by: Xavier Simonart 
> > Signed-off-by: Mohammad Heib 
> > ---
> >   controller/binding.c | 37 +
> >   tests/ovn.at | 37 +
> >   2 files changed, 74 insertions(+)
> >
> > diff --git a/controller/binding.c b/controller/binding.c
> > index 9f5393a92..1221419a9 100644
> > --- a/controller/binding.c
> > +++ b/controller/binding.c
> > @@ -566,6 +566,39 @@ remove_related_lport(const struct
> sbrec_port_binding *pb,
> >   }
> >   }
> >
> > +/*
> > + * Update local_datapath peers when port type changed
> > + * and remove irrelevant ports from this list.
> > + */
> > +static void
> > +update_ld_peers(const struct sbrec_port_binding *pb,
> > + struct hmap *local_datapaths)
> > +{
> > +struct local_datapath *ld =
> > +get_local_datapath(local_datapaths, pb->datapath->tunnel_key);
> > +
> > +if (!ld) {
> > +return;
> > +}
> > +
> > +/*
> > + * This will handle cases where the pb type was explicitly
> > + * changed from router type to any other port type and will
> > + * remove it from the ld peers list.
> > + */
> > +enum en_lport_type type = get_lport_type(pb);
> > +int num_peers = ld->n_peer_ports;
> > +if (type != LP_PATCH) {
> > +remove_local_datapath_peer_port(pb, ld, local_datapaths);
> > +if (num_peers != ld->n_peer_ports) {
> > +static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(1,
> 5);
> > +VLOG_DBG_RL(,
> > +"removing lport %s from the ld peers list",
> > +pb->logical_port);
> > +}
> > +}
> > +}
> > +
> >   static void
> >   delete_active_pb_ras_pd(const struct sbrec_port_binding *pb,
> >   struct shash *ras_pd_map)
> > @@ -2585,6 +2618,10 @@ handle_updated_port(struct binding_ctx_in
> *b_ctx_in,
> >   return true;
> >   }
> >
> > +if (sbrec_port_binding_is_updated(pb, SBREC_PORT_BINDING_COL_TYPE))
> {
> > +update_ld_peers(pb, b_ctx_out->local_datapaths);
> > +}
> > +
> >   update_active_pb_ras_pd(pb, b_ctx_out->local_active_ports_ipv6_pd,
> >   "ipv6_prefix_delegation&

[ovs-dev] [PATCH ovn v3] binding.c: update ld->peers when lsp type updated

2022-08-16 Thread Mohammad Heib
The local_datapath->peer_ports list contains peers pointers
to lsp<-->lrp ports that are supposed to be router end ports,
those pointers are added and deleted to the  local_datapath->peer_ports
when logical switch port of type router are added or deleted from the database.

The deletion and creation of those ports are handled very well when the LSP type
is a router, but if in any case, the user has changed the LSP type from router
port to any other LSP type the ld->peer_ports will keep pointing to this port
and if it was deleted it will keep pointing to invalid memory regions and that
could lead to invalid memory access in the ovn-controller.

To solve the above issue this patch will update the local_dataoath->peer_ports
whenever a lport is updated.

Reported-at: https://bugzilla.redhat.com/show_bug.cgi?id=2077078
Co-authored-by: Xavier Simonart 
Signed-off-by: Mohammad Heib 
Signed-off-by: Xavier Simonart 
Signed-off-by: Mohammad Heib 
---
 controller/binding.c | 37 +
 tests/ovn.at | 37 +
 2 files changed, 74 insertions(+)

diff --git a/controller/binding.c b/controller/binding.c
index 9f5393a92..1221419a9 100644
--- a/controller/binding.c
+++ b/controller/binding.c
@@ -566,6 +566,39 @@ remove_related_lport(const struct sbrec_port_binding *pb,
 }
 }
 
+/*
+ * Update local_datapath peers when port type changed
+ * and remove irrelevant ports from this list.
+ */
+static void
+update_ld_peers(const struct sbrec_port_binding *pb,
+ struct hmap *local_datapaths)
+{
+struct local_datapath *ld =
+get_local_datapath(local_datapaths, pb->datapath->tunnel_key);
+
+if (!ld) {
+return;
+}
+
+/*
+ * This will handle cases where the pb type was explicitly
+ * changed from router type to any other port type and will
+ * remove it from the ld peers list.
+ */
+enum en_lport_type type = get_lport_type(pb);
+int num_peers = ld->n_peer_ports;
+if (type != LP_PATCH) {
+remove_local_datapath_peer_port(pb, ld, local_datapaths);
+if (num_peers != ld->n_peer_ports) {
+static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(1, 5);
+VLOG_DBG_RL(,
+"removing lport %s from the ld peers list",
+pb->logical_port);
+}
+}
+}
+
 static void
 delete_active_pb_ras_pd(const struct sbrec_port_binding *pb,
 struct shash *ras_pd_map)
@@ -2585,6 +2618,10 @@ handle_updated_port(struct binding_ctx_in *b_ctx_in,
 return true;
 }
 
+if (sbrec_port_binding_is_updated(pb, SBREC_PORT_BINDING_COL_TYPE)) {
+update_ld_peers(pb, b_ctx_out->local_datapaths);
+}
+
 update_active_pb_ras_pd(pb, b_ctx_out->local_active_ports_ipv6_pd,
 "ipv6_prefix_delegation");
 
diff --git a/tests/ovn.at b/tests/ovn.at
index c8cc8cde4..79eda21d3 100644
--- a/tests/ovn.at
+++ b/tests/ovn.at
@@ -32404,3 +32404,40 @@ AT_CHECK([test $(ovn-sbctl list fdb | grep -c 
"00:00:00:00:10:30") = 0])
 OVN_CLEANUP([hv1])
 AT_CLEANUP
 ])
+
+OVN_FOR_EACH_NORTHD([
+AT_SETUP([router port type update and then remove])
+ovn_start
+net_add n1
+
+sim_add hv1
+as hv1
+ovs-vsctl add-br br-phys
+ovn_attach n1 br-phys 192.168.0.1
+ovs-vsctl -- add-port br-int hv1-vif1 -- \
+set interface hv1-vif1 external-ids:iface-id=sw0-p1 \
+options:tx_pcap=hv1/vif1-tx.pcap \
+options:rxq_pcap=hv1/vif1-rx.pcap \
+ofport-request=1
+
+check ovn-nbctl ls-add sw0
+check ovn-nbctl lr-add ro0
+check ovn-nbctl lsp-add sw0 sw0-p1
+check ovn-nbctl lsp-add sw0 lsp
+check ovn-nbctl lsp-set-type lsp router
+check ovn-nbctl lsp-set-options lsp router-port=lrp
+check ovn-nbctl lsp-set-addresses lsp  00:00:00:00:00:1
+check ovn-nbctl lrp-add ro0 lrp 00:00:00:00:00:1 aef0:0:0:0:0:0:0:1/64
+check ovn-nbctl set Logical_Router_Port lrp ipv6_ra_configs:send_periodic=true 
\
+-- set Logical_Router_Port lrp ipv6_ra_configs:address_mode=slaac \
+-- set Logical_Router_Port lrp ipv6_ra_configs:mtu=1280 \
+-- set Logical_Router_Port lrp ipv6_ra_configs:max_interval=2 \
+-- set Logical_Router_Port lrp ipv6_ra_configs:min_interval=1
+check ovn-nbctl lsp-set-type lsp localnet
+check ovn-nbctl --wait=hv sync
+check ovn-nbctl lsp-del lsp
+check ovn-nbctl lrp-del lrp
+check ovn-nbctl --wait=hv sync
+OVN_CLEANUP([hv1])
+AT_CLEANUP
+])
-- 
2.34.1

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


Re: [ovs-dev] [PATCH ovn v3] ci: Add missing tests after switch to parallel jobs

2022-08-10 Thread Mohammad Heib
Acked-by: Mohammad Heib 

thanks,


On Wed, Aug 10, 2022 at 3:02 PM Ales Musil  wrote:

> After switch to parallel jobs some tests
> were missing due to way how filtering in autotest
> works. Add additional jobs that filter the !ovn-northd
> which is currently always present when the test calls
> OVN_FOR_EACH_NORTHD.
>
> Fixes: d093905 ("OVN-CI: ovn unit tests run in parallel jobs.")
> Signed-off-by: Ales Musil 
> ---
> v3: Switch to !ovn-northd after suggestion from Mohammad.
> ---
>  .github/workflows/test.yml | 5 +
>  1 file changed, 5 insertions(+)
>
> diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml
> index afa984345..7a59cd478 100644
> --- a/.github/workflows/test.yml
> +++ b/.github/workflows/test.yml
> @@ -40,22 +40,27 @@ jobs:
>  - { compiler: gcc, testsuite: test, testsuite_kw:
> "parallelization=yes,ovn_monitor_all=no" }
>  - { compiler: gcc, testsuite: test, testsuite_kw:
> "parallelization=no,ovn_monitor_all=yes" }
>  - { compiler: gcc, testsuite: test, testsuite_kw:
> "parallelization=no,ovn_monitor_all=no" }
> +- { compiler: gcc, testsuite: test, testsuite_kw: "!ovn-northd" }
>  - { compiler: clang, testsuite: test, sanitizers: sanitizers,
> testsuite_kw: "parallelization=yes,ovn_monitor_all=yes" }
>  - { compiler: clang, testsuite: test, sanitizers: sanitizers,
> testsuite_kw: "parallelization=yes,ovn_monitor_all=no" }
>  - { compiler: clang, testsuite: test, sanitizers: sanitizers,
> testsuite_kw: "parallelization=no,ovn_monitor_all=yes" }
>  - { compiler: clang, testsuite: test, sanitizers: sanitizers,
> testsuite_kw: "parallelization=no,ovn_monitor_all=no" }
> +- { compiler: clang, testsuite: test, sanitizers: sanitizers,
> testsuite_kw: "!ovn-northd" }
>  - { compiler: gcc, testsuite: test, libs: -ljemalloc,
> testsuite_kw: "parallelization=yes,ovn_monitor_all=yes" }
>  - { compiler: gcc, testsuite: test, libs: -ljemalloc,
> testsuite_kw: "parallelization=yes,ovn_monitor_all=no" }
>  - { compiler: gcc, testsuite: test, libs: -ljemalloc,
> testsuite_kw: "parallelization=no,ovn_monitor_all=yes" }
>  - { compiler: gcc, testsuite: test, libs: -ljemalloc,
> testsuite_kw: "parallelization=no,ovn_monitor_all=no" }
> +- { compiler: gcc, testsuite: test, libs: -ljemalloc,
> testsuite_kw: "!ovn-northd" }
>  - { compiler: clang, testsuite: test, libs: -ljemalloc,
> testsuite_kw: "parallelization=yes,ovn_monitor_all=yes" }
>  - { compiler: clang, testsuite: test, libs: -ljemalloc,
> testsuite_kw: "parallelization=yes,ovn_monitor_all=no" }
>  - { compiler: clang, testsuite: test, libs: -ljemalloc,
> testsuite_kw: "parallelization=no,ovn_monitor_all=yes" }
>  - { compiler: clang, testsuite: test, libs: -ljemalloc,
> testsuite_kw: "parallelization=no,ovn_monitor_all=no" }
> +- { compiler: clang, testsuite: test, libs: -ljemalloc,
> testsuite_kw: "!ovn-northd" }
>  - { compiler: gcc, testsuite: system-test, testsuite_kw:
> "parallelization=yes,ovn_monitor_all=yes" }
>  - { compiler: gcc, testsuite: system-test, testsuite_kw:
> "parallelization=yes,ovn_monitor_all=no" }
>  - { compiler: gcc, testsuite: system-test, testsuite_kw:
> "parallelization=no,ovn_monitor_all=yes" }
>  - { compiler: gcc, testsuite: system-test, testsuite_kw:
> "parallelization=no,ovn_monitor_all=no" }
> +- { compiler: gcc, testsuite: system-test, testsuite_kw:
> "!ovn-northd" }
>  - { compiler: gcc,  m32: m32, opts: --disable-ssl}
>
>  steps:
> --
> 2.37.1
>
> ___
> 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


[ovs-dev] [PATCH ovn]OVN-CI: ovn unit tests run in parallel jobs.

2022-08-04 Thread Mohammad Heib
Ovn unit tests supported matrix size has been increased
after adding support to monitor_all and northd_parallelization
options recently, and that increased the execution time of the ovn-ci jobs.

This patch aims to reduce the execution time of those jobs by splitting
them into smaller jobs that runs in parallel and each one will execute
a subset of unit test.

Reported-at: https://bugzilla.redhat.com/show_bug.cgi?id=2114862
Signed-off-by: Mohammad Heib 
---
 .ci/linux-build.sh |  9 +++--
 .github/workflows/test.yml | 26 +-
 2 files changed, 28 insertions(+), 7 deletions(-)

diff --git a/.ci/linux-build.sh b/.ci/linux-build.sh
index dc32564fa..2b0782aea 100755
--- a/.ci/linux-build.sh
+++ b/.ci/linux-build.sh
@@ -47,10 +47,15 @@ else
 fi
 
 if [ "$TESTSUITE" ]; then
+TESTSUITEFLAGS=""
+if [[ ! -z $TESTSUITE_KW ]]; then
+TESTSUITEFLAGS="-k $TESTSUITE_KW"
+fi
+
 if [ "$TESTSUITE" = "system-test" ]; then
 configure_ovn $OPTS
 make -j4 || { cat config.log; exit 1; }
-if ! sudo make -j4 check-kernel RECHECK=yes; then
+if ! sudo make -j4 check-kernel TESTSUITEFLAGS="$TESTSUITEFLAGS" 
RECHECK=yes; then
 # system-kmod-testsuite.log is necessary for debugging.
 cat tests/system-kmod-testsuite.log
 exit 1
@@ -62,7 +67,7 @@ if [ "$TESTSUITE" ]; then
 
 export DISTCHECK_CONFIGURE_FLAGS="$OPTS"
 if ! make distcheck CFLAGS="${COMMON_CFLAGS} ${OVN_CFLAGS}" -j4 \
-TESTSUITEFLAGS="-j4" RECHECK=yes
+TESTSUITEFLAGS="$TESTSUITEFLAGS -j4" RECHECK=yes
 then
 # testsuite.log is necessary for debugging.
 cat */_build/sub/tests/testsuite.log
diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml
index 3b7283229..83d7c2386 100644
--- a/.github/workflows/test.yml
+++ b/.github/workflows/test.yml
@@ -24,6 +24,7 @@ jobs:
   M32: ${{ matrix.cfg.m32 }}
   OPTS:${{ matrix.cfg.opts }}
   TESTSUITE:   ${{ matrix.cfg.testsuite }}
+  TESTSUITE_KW:   ${{ matrix.cfg.testsuite_kw }}
   SANITIZERS:  ${{ matrix.cfg.sanitizers }}
 
 name: linux ${{ join(matrix.cfg.*, ' ') }}
@@ -35,11 +36,26 @@ jobs:
 cfg:
 - { compiler: gcc, opts: --disable-ssl }
 - { compiler: clang, opts: --disable-ssl }
-- { compiler: gcc, testsuite: test }
-- { compiler: gcc, testsuite: system-test }
-- { compiler: clang, testsuite: test, sanitizers: sanitizers }
-- { compiler: gcc, testsuite: test, libs: -ljemalloc }
-- { compiler: clang, testsuite: test, libs: -ljemalloc }
+- { compiler: gcc, testsuite: test, testsuite_kw: 
"parallelization=yes,ovn_monitor_all=yes" }
+- { compiler: gcc, testsuite: test, testsuite_kw: 
"parallelization=yes,ovn_monitor_all=no" }
+- { compiler: gcc, testsuite: test, testsuite_kw: 
"parallelization=no,ovn_monitor_all=yes" }
+- { compiler: gcc, testsuite: test, testsuite_kw: 
"parallelization=no,ovn_monitor_all=no" }
+- { compiler: clang, testsuite: test, sanitizers: sanitizers, 
testsuite_kw: "parallelization=yes,ovn_monitor_all=yes" }
+- { compiler: clang, testsuite: test, sanitizers: sanitizers, 
testsuite_kw: "parallelization=yes,ovn_monitor_all=no" }
+- { compiler: clang, testsuite: test, sanitizers: sanitizers, 
testsuite_kw: "parallelization=no,ovn_monitor_all=yes" }
+- { compiler: clang, testsuite: test, sanitizers: sanitizers, 
testsuite_kw: "parallelization=no,ovn_monitor_all=no" }
+- { compiler: gcc, testsuite: test, libs: -ljemalloc, testsuite_kw: 
"parallelization=yes,ovn_monitor_all=yes" }
+- { compiler: gcc, testsuite: test, libs: -ljemalloc, testsuite_kw: 
"parallelization=yes,ovn_monitor_all=no" }
+- { compiler: gcc, testsuite: test, libs: -ljemalloc, testsuite_kw: 
"parallelization=no,ovn_monitor_all=yes" }
+- { compiler: gcc, testsuite: test, libs: -ljemalloc, testsuite_kw: 
"parallelization=no,ovn_monitor_all=no" }
+- { compiler: clang, testsuite: test, libs: -ljemalloc, testsuite_kw: 
"parallelization=yes,ovn_monitor_all=yes" }
+- { compiler: clang, testsuite: test, libs: -ljemalloc, testsuite_kw: 
"parallelization=yes,ovn_monitor_all=no" }
+- { compiler: clang, testsuite: test, libs: -ljemalloc, testsuite_kw: 
"parallelization=no,ovn_monitor_all=yes" }
+- { compiler: clang, testsuite: test, libs: -ljemalloc, testsuite_kw: 
"parallelization=no,ovn_monitor_all=no" }
+- { compiler: gcc, testsuite: system-test, testsuite_kw: 
"parallelization=yes,ovn_monitor_all=yes" }
+- { compiler: 

[ovs-dev] [PATCH ovn v2] binding.c: update ld->peers when lsp type updated

2022-08-03 Thread Mohammad Heib
The local_datapath->peer_ports list contains peers pointers
to lsp<-->lrp ports that are supposed to be router end ports,
those pointers are added and deleted to the  local_datapath->peer_ports
when logical switch port of type router are added or deleted from the database.

The deletion and creation of those ports are handled very well when the LSP type
is a router, but if in any case, the user has changed the LSP type from router
port to any other LSP type the ld->peer_ports will keep pointing to this port
and if it was deleted it will keep pointing to invalid memory regions and that
could lead to invalid memory access in the ovn-controller.

To solve the above issue this patch will update the local_dataoath->peer_ports
whenever a lport is updated.

Reported-at: https://bugzilla.redhat.com/show_bug.cgi?id=2077078
Co-authored-by: Xavier Simonart 
Signed-off-by: Mohammad Heib 
Signed-off-by: Xavier Simonart 
---
 controller/binding.c | 33 +
 tests/ovn.at | 33 +
 2 files changed, 66 insertions(+)

diff --git a/controller/binding.c b/controller/binding.c
index 19b28369f..3bd8f2ada 100644
--- a/controller/binding.c
+++ b/controller/binding.c
@@ -505,6 +505,38 @@ remove_related_lport(const struct sbrec_port_binding *pb,
 }
 }
 
+/*
+ * Update local_datapath peers when port type changed
+ * and remove irrelevant ports from this list.
+ */
+static void
+update_ld_peers(const struct sbrec_port_binding *pb,
+ struct hmap *local_datapaths)
+{
+struct local_datapath *ld = get_local_datapath(
+local_datapaths, pb->datapath->tunnel_key);
+if (!ld) {
+return;
+}
+
+/*
+ * This will handle cases where the pb type was explicitly
+ * changed from router type to any other port type and will
+ * remove it from the ld peers list.
+ */
+enum en_lport_type type = get_lport_type(pb);
+int num_peers = ld->n_peer_ports;
+if (type != LP_PATCH) {
+remove_local_datapath_peer_port(pb, ld, local_datapaths);
+if (num_peers != ld->n_peer_ports) {
+static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(1, 5);
+VLOG_DBG_RL(,
+"removing lport %s from the ld peers list",
+pb->logical_port);
+}
+}
+}
+
 static void
 delete_active_pb_ras_pd(const struct sbrec_port_binding *pb,
 struct shash *ras_pd_map)
@@ -2612,6 +2644,7 @@ delete_done:
 continue;
 }
 
+update_ld_peers(pb, b_ctx_out->local_datapaths);
 update_active_pb_ras_pd(pb, b_ctx_out->local_active_ports_ipv6_pd,
 "ipv6_prefix_delegation");
 
diff --git a/tests/ovn.at b/tests/ovn.at
index 3ba6ced4e..54673e9ec 100644
--- a/tests/ovn.at
+++ b/tests/ovn.at
@@ -32349,3 +32349,36 @@ AT_CHECK([test $(ovn-sbctl list fdb | grep -c 
"00:00:00:00:10:30") = 0])
 OVN_CLEANUP([hv1])
 AT_CLEANUP
 ])
+
+OVN_FOR_EACH_NORTHD([
+AT_SETUP([router port type update and then remove])
+ovn_start
+net_add n1
+
+sim_add hv1
+as hv1
+ovs-vsctl add-br br-phys
+ovn_attach n1 br-phys 192.168.0.1
+ovs-vsctl -- add-port br-int hv1-vif1 -- \
+set interface hv1-vif1 external-ids:iface-id=sw0-p1 \
+options:tx_pcap=hv1/vif1-tx.pcap \
+options:rxq_pcap=hv1/vif1-rx.pcap \
+ofport-request=1
+
+check ovn-nbctl ls-add sw0
+check ovn-nbctl lr-add ro0
+check ovn-nbctl lsp-add sw0 sw0-p1
+check ovn-nbctl lsp-add sw0 lsp
+check ovn-nbctl lsp-set-type lsp router
+check ovn-nbctl lsp-set-options lsp router-port=lrp
+check ovn-nbctl lsp-set-addresses lsp  00:00:00:00:00:1
+check ovn-nbctl lrp-add ro0 lrp 00:00:00:00:00:1 aef0:0:0:0:0:0:0:1/64
+check ovn-nbctl set Logical_Router_Port lrp ipv6_ra_configs:send_periodic=true 
-- set Logical_Router_Port lrp ipv6_ra_configs:address_mode=slaac -- set 
Logical_Router_Port lrp ipv6_ra_configs:mtu=1280 -- set Logical_Router_Port lrp 
ipv6_ra_configs:max_interval=2 -- set Logical_Router_Port lrp 
ipv6_ra_configs:min_interval=1
+check ovn-nbctl lsp-set-type lsp localnet
+check ovn-nbctl --wait=hv sync
+check ovn-nbctl lsp-del lsp
+check ovn-nbctl lrp-del lrp
+check ovn-nbctl --wait=hv sync
+OVN_CLEANUP([hv1])
+AT_CLEANUP
+])
-- 
2.34.1

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


[ovs-dev] binding.c: update ld->peers when lsp type updated

2022-08-03 Thread Mohammad Heib
The local_datapath->peer_ports list contains peers pointers
to lsp<-->lrp ports that are supposed to be router end ports,
those pointers are added and deleted to the  local_datapath->peer_ports
when logical switch port of type router are added or deleted from the database.

The deletion and creation of those ports are handled very well when the LSP type
is a router, but if in any case, the user has changed the LSP type from router
port to any other LSP type the ld->peer_ports will keep pointing to this port
and if it was deleted it will keep pointing to invalid memory regions and that
could lead to invalid memory access in the ovn-controller.

To solve the above issue this patch will update the local_dataoath->peer_ports
whenever a lport is updated.

Reported-at: https://bugzilla.redhat.com/show_bug.cgi?id=2077078
Co-authored-by: Xavier Simonart 
Signed-off-by: Mohammad Heib 
Signed-off-by: Xavier Simonart 
---
 controller/binding.c | 33 +
 tests/ovn.at | 33 +
 2 files changed, 66 insertions(+)

diff --git a/controller/binding.c b/controller/binding.c
index 19b28369f..3bd8f2ada 100644
--- a/controller/binding.c
+++ b/controller/binding.c
@@ -505,6 +505,38 @@ remove_related_lport(const struct sbrec_port_binding *pb,
 }
 }
 
+/*
+ * Update local_datapath peers when port type changed
+ * and remove irrelevant ports from this list.
+ */
+static void
+update_ld_peers(const struct sbrec_port_binding *pb,
+ struct hmap *local_datapaths)
+{
+struct local_datapath *ld = get_local_datapath(
+local_datapaths, pb->datapath->tunnel_key);
+if (!ld) {
+return;
+}
+
+/*
+ * This will handle cases where the pb type was explicitly
+ * changed from router type to any other port type and will
+ * remove it from the ld peers list.
+ */
+enum en_lport_type type = get_lport_type(pb);
+int num_peers = ld->n_peer_ports;
+if (type != LP_PATCH) {
+remove_local_datapath_peer_port(pb, ld, local_datapaths);
+if (num_peers != ld->n_peer_ports) {
+static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(1, 5);
+VLOG_DBG_RL(,
+"removing lport %s from the ld peers list",
+pb->logical_port);
+}
+}
+}
+
 static void
 delete_active_pb_ras_pd(const struct sbrec_port_binding *pb,
 struct shash *ras_pd_map)
@@ -2612,6 +2644,7 @@ delete_done:
 continue;
 }
 
+update_ld_peers(pb, b_ctx_out->local_datapaths);
 update_active_pb_ras_pd(pb, b_ctx_out->local_active_ports_ipv6_pd,
 "ipv6_prefix_delegation");
 
diff --git a/tests/ovn.at b/tests/ovn.at
index 3ba6ced4e..54673e9ec 100644
--- a/tests/ovn.at
+++ b/tests/ovn.at
@@ -32349,3 +32349,36 @@ AT_CHECK([test $(ovn-sbctl list fdb | grep -c 
"00:00:00:00:10:30") = 0])
 OVN_CLEANUP([hv1])
 AT_CLEANUP
 ])
+
+OVN_FOR_EACH_NORTHD([
+AT_SETUP([router port type update and then remove])
+ovn_start
+net_add n1
+
+sim_add hv1
+as hv1
+ovs-vsctl add-br br-phys
+ovn_attach n1 br-phys 192.168.0.1
+ovs-vsctl -- add-port br-int hv1-vif1 -- \
+set interface hv1-vif1 external-ids:iface-id=sw0-p1 \
+options:tx_pcap=hv1/vif1-tx.pcap \
+options:rxq_pcap=hv1/vif1-rx.pcap \
+ofport-request=1
+
+check ovn-nbctl ls-add sw0
+check ovn-nbctl lr-add ro0
+check ovn-nbctl lsp-add sw0 sw0-p1
+check ovn-nbctl lsp-add sw0 lsp
+check ovn-nbctl lsp-set-type lsp router
+check ovn-nbctl lsp-set-options lsp router-port=lrp
+check ovn-nbctl lsp-set-addresses lsp  00:00:00:00:00:1
+check ovn-nbctl lrp-add ro0 lrp 00:00:00:00:00:1 aef0:0:0:0:0:0:0:1/64
+check ovn-nbctl set Logical_Router_Port lrp ipv6_ra_configs:send_periodic=true 
-- set Logical_Router_Port lrp ipv6_ra_configs:address_mode=slaac -- set 
Logical_Router_Port lrp ipv6_ra_configs:mtu=1280 -- set Logical_Router_Port lrp 
ipv6_ra_configs:max_interval=2 -- set Logical_Router_Port lrp 
ipv6_ra_configs:min_interval=1
+check ovn-nbctl lsp-set-type lsp localnet
+check ovn-nbctl --wait=hv sync
+check ovn-nbctl lsp-del lsp
+check ovn-nbctl lrp-del lrp
+check ovn-nbctl --wait=hv sync
+OVN_CLEANUP([hv1])
+AT_CLEANUP
+])
-- 
2.34.1

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


[ovs-dev] [PATCH ovn] CI-Actions: define matrix as a list

2022-08-03 Thread Mohammad Heib
Defining the matrix as a list will make it more readable
and easy to extend also users can exclude and add new cases
without using include, exclude just add  a new combination
to the list.

Signed-off-by: Mohammad Heib 
---
 .github/workflows/test.yml | 55 ++
 1 file changed, 20 insertions(+), 35 deletions(-)

diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml
index 49c20f589..3b7283229 100644
--- a/.github/workflows/test.yml
+++ b/.github/workflows/test.yml
@@ -19,43 +19,28 @@ jobs:
 libssl-dev llvm-dev libelf-dev libnuma-dev libpcap-dev  \
 selinux-policy-dev ncat python3-scapy isc-dhcp-server
   m32_dependecies: gcc-multilib
-  CC:  ${{ matrix.compiler }}
-  LIBS:${{ matrix.libs }}
-  M32: ${{ matrix.m32 }}
-  OPTS:${{ matrix.opts }}
-  TESTSUITE:   ${{ matrix.testsuite }}
-  SANITIZERS:  ${{ matrix.sanitizers }}
-
-name: linux ${{ join(matrix.*, ' ') }}
+  CC:  ${{ matrix.cfg.compiler }}
+  LIBS:${{ matrix.cfg.libs }}
+  M32: ${{ matrix.cfg.m32 }}
+  OPTS:${{ matrix.cfg.opts }}
+  TESTSUITE:   ${{ matrix.cfg.testsuite }}
+  SANITIZERS:  ${{ matrix.cfg.sanitizers }}
+
+name: linux ${{ join(matrix.cfg.*, ' ') }}
 runs-on: ubuntu-20.04
 
 strategy:
   fail-fast: false
   matrix:
-include:
-  - compiler: gcc
-opts: --disable-ssl
-  - compiler: clang
-opts: --disable-ssl
-
-  - compiler: gcc
-testsuite:test
-  - compiler: gcc
-testsuite:system-test
-  - compiler: clang
-testsuite:test
-sanitizers:   sanitizers
-
-  - compiler: gcc
-testsuite:test
-libs: -ljemalloc
-  - compiler: clang
-testsuite:test
-libs: -ljemalloc
-
-  - compiler: gcc
-m32:  m32
-opts: --disable-ssl
+cfg:
+- { compiler: gcc, opts: --disable-ssl }
+- { compiler: clang, opts: --disable-ssl }
+- { compiler: gcc, testsuite: test }
+- { compiler: gcc, testsuite: system-test }
+- { compiler: clang, testsuite: test, sanitizers: sanitizers }
+- { compiler: gcc, testsuite: test, libs: -ljemalloc }
+- { compiler: clang, testsuite: test, libs: -ljemalloc }
+- { compiler: gcc,  m32: m32, opts: --disable-ssl}
 
 steps:
 - name: checkout
@@ -89,11 +74,11 @@ jobs:
   run:  sudo apt install -y ${{ env.dependencies }}
 
 - name: install libunbound libunwind
-  if:   matrix.m32 == ''
+  if:   matrix.cfg.m32 == ''
   run:  sudo apt install -y libunbound-dev libunwind-dev
 
 - name: install 32-bit dependencies
-  if:   matrix.m32 != ''
+  if:   matrix.cfg.m32 != ''
   run:  sudo apt install -y ${{ env.m32_dependecies }}
 
 - name: update PATH
@@ -131,7 +116,7 @@ jobs:
   if: failure() || cancelled()
   uses: actions/upload-artifact@v2
   with:
-name: logs-linux-${{ join(matrix.*, '-') }}
+name: logs-linux-${{ join(matrix.cfg.*, '-') }}
 path: logs.tgz
 
   build-osx:
-- 
2.34.1

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


[ovs-dev] [PATCH ovn v2] northd: handle virtual lport type update

2022-08-02 Thread Mohammad Heib
ovn-northd re-create sbrec row for lport of type
virtual when the type explicitly updated in NBDB.

This approach was applied to handle container lport
type updates and avoid handling issues in the ovn-controller,
this patch expanded that approach to handle lport of type
virtual in the same way.

Reported-at: https://bugzilla.redhat.com/show_bug.cgi?id=2099288
Fixes: cd3b685043fa (northd: handle container lport type update)
Signed-off-by: Mohammad Heib 
Acked-by: Dumitru Ceara 
---
 northd/northd.c | 31 ++-
 1 file changed, 18 insertions(+), 13 deletions(-)

diff --git a/northd/northd.c b/northd/northd.c
index d31cb1688..5ce352666 100644
--- a/northd/northd.c
+++ b/northd/northd.c
@@ -1856,9 +1856,9 @@ localnet_can_learn_mac(const struct 
nbrec_logical_switch_port *nbsp)
 static bool
 lsp_is_type_changed(const struct sbrec_port_binding *sb,
 const struct nbrec_logical_switch_port *nbsp,
-bool *is_old_container_lport)
+bool *update_sbrec)
 {
-*is_old_container_lport = false;
+*update_sbrec = false;
 if (!sb || !nbsp) {
 return false;
 }
@@ -1870,13 +1870,19 @@ lsp_is_type_changed(const struct sbrec_port_binding *sb,
  */
 if ((!sb->parent_port && nbsp->parent_name) ||
 (sb->parent_port && !nbsp->parent_name)) {
-*is_old_container_lport = true;
+*update_sbrec = true;
 return true;
 } else {
 return false;
 }
 }
 
+/* Cover cases where port changed to/from virtual port */
+if (!strcmp(sb->type, "virtual") ||
+!strcmp(nbsp->type, "virtual")) {
+*update_sbrec = true;
+}
+
 /* Both lports are not "VIF's" it is safe to use strcmp. */
 if (sb->type[0] && nbsp->type[0]) {
 return strcmp(sb->type, nbsp->type);
@@ -2598,19 +2604,18 @@ join_logical_ports(struct northd_input *input_data,
  *created one and recompute everything that is needed
  *for this lport.
  *
- * This change will affect container lport type changes
- * only for now, this change is needed in container
- * lport cases to avoid port type conflicts in the
- * ovn-controller when the user clears the parent_port
- * field in the container lport.
+ * This change will affect container/virtual lport type
+ * changes only for now, this change is needed in
+ * contaier/virtual lport cases to avoid port type
+ * conflicts in the ovn-controller when the user clears
+ * the parent_port field in the container lport or updated
+ * the lport type.
  *
- * This approach can be applied to all other lport types
- * changes by removing the is_old_container_lport.
  */
-bool is_old_container_lport = false;
+bool update_sbrec = false;
 if (op->sb && lsp_is_type_changed(op->sb, nbsp,
-  _old_container_lport)
-   && is_old_container_lport) {
+  _sbrec)
+   && update_sbrec) {
 ovs_list_remove(>list);
 sbrec_port_binding_delete(op->sb);
 ovn_port_destroy(ports, op);
-- 
2.34.1

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


Re: [ovs-dev] [PATCH ovn] northd: handle virtual lport type update

2022-08-02 Thread Mohammad Heib
On Tue, Aug 2, 2022 at 5:00 PM Dumitru Ceara  wrote:

> On 8/2/22 15:56, Mohammad Heib wrote:
> > HI Dumitru,
> > thank you for reviewing the patch,
> >
> >
> > On Tue, Aug 2, 2022 at 1:27 PM Dumitru Ceara  wrote:
> >
> >> On 7/19/22 15:33, Mohammad Heib wrote:
> >>> ovn-northd re-create sbrec row for lport of type
> >>> virtual when the type explicitly updated in NBDB.
> >>>
> >>> This approach was applied to handle container lport
> >>> type updates and avoid handling issues in the ovn-controller,
> >>> this patch expanded that approach to handle lport of type
> >>> virtual in the same way.
> >>>
> >>> Reported-at: https://bugzilla.redhat.com/show_bug.cgi?id=2099288
> >>> Fixes: cd3b685043fa (northd: handle container lport type update)
> >>> Signed-off-by: Mohammad Heib 
> >>> ---
> >>
> >> Hi Mohammad,
> >>
> >> Just a small comment below; with that addressed feel free to add my ack
> >> to v2:
> >>
> >> Acked-by: Dumitru Ceara 
> >>
> >>>  northd/northd.c | 31 ++-
> >>>  1 file changed, 18 insertions(+), 13 deletions(-)
> >>>
> >>> diff --git a/northd/northd.c b/northd/northd.c
> >>> index d31cb1688..d587bc98d 100644
> >>> --- a/northd/northd.c
> >>> +++ b/northd/northd.c
> >>> @@ -1856,9 +1856,9 @@ localnet_can_learn_mac(const struct
> >> nbrec_logical_switch_port *nbsp)
> >>>  static bool
> >>>  lsp_is_type_changed(const struct sbrec_port_binding *sb,
> >>>  const struct nbrec_logical_switch_port *nbsp,
> >>> -bool *is_old_container_lport)
> >>> +bool *update_sbrec)
> >>>  {
> >>> -*is_old_container_lport = false;
> >>> +*update_sbrec = false;
> >>>  if (!sb || !nbsp) {
> >>>  return false;
> >>>  }
> >>> @@ -1870,13 +1870,19 @@ lsp_is_type_changed(const struct
> >> sbrec_port_binding *sb,
> >>>   */
> >>>  if ((!sb->parent_port && nbsp->parent_name) ||
> >>>  (sb->parent_port && !nbsp->parent_name)) {
> >>> -*is_old_container_lport = true;
> >>> +*update_sbrec = true;
> >>>  return true;
> >>>  } else {
> >>>  return false;
> >>>  }
> >>>  }
> >>>
> >>> +/* Cover cases where port changed to/from virtual port */
> >>> +if ((sb->type[0] && !strcmp(sb->type, "virtual"))||
> >>> +(nbsp->type[0] && !strcmp(nbsp->type, "virtual"))) {
> >>
> >> There's no need to check for sb->type[0] and nbsp->type[0].
> >>
> > actually, i want to make sure that I'm not doing strcmp with VIF
> port(null
> > type) that will lead to undefined behavior in strcmp.
> >
>
> Well, "sb->type[0]" is still undefined behavior if sb->type is NULL.  In
> any case, sb->type and nbsp->type can never be NULL.  The IDL code
> ensures the default to be "".
>
 yes you are right  sb->type[0] will be indeed undefined behavior if
sb->type is NULL,
i submitted v2 that addresses the comments above,
thank you.

>
> >>
> >> Also, there's a missing space before "||".
> >>
> > i added space to V2
> >
>
> Thanks!
>
>
___
dev mailing list
d...@openvswitch.org
https://mail.openvswitch.org/mailman/listinfo/ovs-dev


Re: [ovs-dev] [PATCH ovn] northd: handle virtual lport type update

2022-08-02 Thread Mohammad Heib
HI Dumitru,
thank you for reviewing the patch,


On Tue, Aug 2, 2022 at 1:27 PM Dumitru Ceara  wrote:

> On 7/19/22 15:33, Mohammad Heib wrote:
> > ovn-northd re-create sbrec row for lport of type
> > virtual when the type explicitly updated in NBDB.
> >
> > This approach was applied to handle container lport
> > type updates and avoid handling issues in the ovn-controller,
> > this patch expanded that approach to handle lport of type
> > virtual in the same way.
> >
> > Reported-at: https://bugzilla.redhat.com/show_bug.cgi?id=2099288
> > Fixes: cd3b685043fa (northd: handle container lport type update)
> > Signed-off-by: Mohammad Heib 
> > ---
>
> Hi Mohammad,
>
> Just a small comment below; with that addressed feel free to add my ack
> to v2:
>
> Acked-by: Dumitru Ceara 
>
> >  northd/northd.c | 31 ++-
> >  1 file changed, 18 insertions(+), 13 deletions(-)
> >
> > diff --git a/northd/northd.c b/northd/northd.c
> > index d31cb1688..d587bc98d 100644
> > --- a/northd/northd.c
> > +++ b/northd/northd.c
> > @@ -1856,9 +1856,9 @@ localnet_can_learn_mac(const struct
> nbrec_logical_switch_port *nbsp)
> >  static bool
> >  lsp_is_type_changed(const struct sbrec_port_binding *sb,
> >  const struct nbrec_logical_switch_port *nbsp,
> > -bool *is_old_container_lport)
> > +bool *update_sbrec)
> >  {
> > -*is_old_container_lport = false;
> > +*update_sbrec = false;
> >  if (!sb || !nbsp) {
> >  return false;
> >  }
> > @@ -1870,13 +1870,19 @@ lsp_is_type_changed(const struct
> sbrec_port_binding *sb,
> >   */
> >  if ((!sb->parent_port && nbsp->parent_name) ||
> >  (sb->parent_port && !nbsp->parent_name)) {
> > -*is_old_container_lport = true;
> > +*update_sbrec = true;
> >  return true;
> >  } else {
> >  return false;
> >  }
> >  }
> >
> > +/* Cover cases where port changed to/from virtual port */
> > +if ((sb->type[0] && !strcmp(sb->type, "virtual"))||
> > +(nbsp->type[0] && !strcmp(nbsp->type, "virtual"))) {
>
> There's no need to check for sb->type[0] and nbsp->type[0].
>
actually, i want to make sure that I'm not doing strcmp with VIF port(null
type) that will lead to undefined behavior in strcmp.

>
> Also, there's a missing space before "||".
>
i added space to V2

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


[ovs-dev] [PATCH ovn] northd: handle virtual lport type update

2022-07-19 Thread Mohammad Heib
ovn-northd re-create sbrec row for lport of type
virtual when the type explicitly updated in NBDB.

This approach was applied to handle container lport
type updates and avoid handling issues in the ovn-controller,
this patch expanded that approach to handle lport of type
virtual in the same way.

Reported-at: https://bugzilla.redhat.com/show_bug.cgi?id=2099288
Fixes: cd3b685043fa (northd: handle container lport type update)
Signed-off-by: Mohammad Heib 
---
 northd/northd.c | 31 ++-
 1 file changed, 18 insertions(+), 13 deletions(-)

diff --git a/northd/northd.c b/northd/northd.c
index d31cb1688..d587bc98d 100644
--- a/northd/northd.c
+++ b/northd/northd.c
@@ -1856,9 +1856,9 @@ localnet_can_learn_mac(const struct 
nbrec_logical_switch_port *nbsp)
 static bool
 lsp_is_type_changed(const struct sbrec_port_binding *sb,
 const struct nbrec_logical_switch_port *nbsp,
-bool *is_old_container_lport)
+bool *update_sbrec)
 {
-*is_old_container_lport = false;
+*update_sbrec = false;
 if (!sb || !nbsp) {
 return false;
 }
@@ -1870,13 +1870,19 @@ lsp_is_type_changed(const struct sbrec_port_binding *sb,
  */
 if ((!sb->parent_port && nbsp->parent_name) ||
 (sb->parent_port && !nbsp->parent_name)) {
-*is_old_container_lport = true;
+*update_sbrec = true;
 return true;
 } else {
 return false;
 }
 }
 
+/* Cover cases where port changed to/from virtual port */
+if ((sb->type[0] && !strcmp(sb->type, "virtual"))||
+(nbsp->type[0] && !strcmp(nbsp->type, "virtual"))) {
+*update_sbrec = true;
+}
+
 /* Both lports are not "VIF's" it is safe to use strcmp. */
 if (sb->type[0] && nbsp->type[0]) {
 return strcmp(sb->type, nbsp->type);
@@ -2598,19 +2604,18 @@ join_logical_ports(struct northd_input *input_data,
  *created one and recompute everything that is needed
  *for this lport.
  *
- * This change will affect container lport type changes
- * only for now, this change is needed in container
- * lport cases to avoid port type conflicts in the
- * ovn-controller when the user clears the parent_port
- * field in the container lport.
+ * This change will affect container/virtual lport type
+ * changes only for now, this change is needed in
+ * contaier/virtual lport cases to avoid port type
+ * conflicts in the ovn-controller when the user clears
+ * the parent_port field in the container lport or updated
+ * the lport type.
  *
- * This approach can be applied to all other lport types
- * changes by removing the is_old_container_lport.
  */
-bool is_old_container_lport = false;
+bool update_sbrec = false;
 if (op->sb && lsp_is_type_changed(op->sb, nbsp,
-  _old_container_lport)
-   && is_old_container_lport) {
+  _sbrec)
+   && update_sbrec) {
 ovs_list_remove(>list);
 sbrec_port_binding_delete(op->sb);
 ovn_port_destroy(ports, op);
-- 
2.34.1

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


[ovs-dev] [PATCH ovn v4] OVN-CI: Add test cases with monitor-all enabled.

2022-06-30 Thread Mohammad Heib
currently ovn ci only has one test case with the option
ovn-monitor-all enabled, this patch will add one more
execution with option ovn-monitor-all=true for each test case that
are wrapped by OVN_FOR_EACH_NORTHD macro.

This will more or less double the number of test cases.
It is possible to select a reduce set of test cases using -k "keywords".
Keyword such as
dp-groups=yes
dp-groups=no
parallelization=yes
parallelization=no
ovn-northd
ovn-northd-ddlog
ovn_monitor_all=yes
can be used to select a range of tests, as title is searched as well.

For instance, to run ovn-monitor-all tests, with dp-groups enabled and ddlog 
disabled:
make check TESTSUITEFLAGS="-k 
dp-groups=yes,ovn_monitor_all=yes,\!ovn-northd-ddlog"

Signed-off-by: Mohammad Heib 
---
 tests/ovn-macros.at | 19 +++
 tests/ovs-macros.at |  4 +++-
 2 files changed, 18 insertions(+), 5 deletions(-)

diff --git a/tests/ovn-macros.at b/tests/ovn-macros.at
index 335f9158c..b71d02d44 100644
--- a/tests/ovn-macros.at
+++ b/tests/ovn-macros.at
@@ -323,6 +323,15 @@ ovn_az_attach() {
 -- --may-exist add-br br-int \
 -- set bridge br-int fail-mode=secure 
other-config:disable-in-band=true \
 || return 1
+
+# currently this is the optimal place to add the ovn-monitor-all=true 
option,
+# this can be implemented in a different way by redefining the sim-add 
function
+# to add the ovn-related external-ids when we add a new simulated node via 
sim-add.
+#
+if test X$OVN_MONITOR_ALL = Xyes; then
+ovs-vsctl set open . external_ids:ovn-monitor-all=true
+fi
+
 start_daemon ovn-controller --enable-dummy-vif-plug || return 1
 }
 
@@ -750,12 +759,14 @@ m4_define([OVN_POPULATE_ARP], 
[AT_CHECK(ovn_populate_arp__, [0], [ignore])])
 m4_define([OVN_FOR_EACH_NORTHD],
   [m4_foreach([NORTHD_TYPE], [ovn-northd],
  [m4_foreach([NORTHD_USE_DP_GROUPS], [yes, no],
-   [m4_foreach([NORTHD_USE_PARALLELIZATION], [yes, no], [$1
-])])])])
+   [m4_foreach([NORTHD_USE_PARALLELIZATION], [yes, no],
+ [m4_foreach([OVN_MONITOR_ALL], [yes, no], [$1
+])])])])])
 
 # Some tests aren't prepared for dp groups to be enabled.
 m4_define([OVN_FOR_EACH_NORTHD_WITHOUT_DP_GROUPS],
   [m4_foreach([NORTHD_TYPE], [ovn-northd],
  [m4_foreach([NORTHD_USE_DP_GROUPS], [no],
-   [m4_foreach([NORTHD_USE_PARALLELIZATION], [yes, no], [$1
-])])])])
+   [m4_foreach([NORTHD_USE_PARALLELIZATION], [yes, no],
+ [m4_foreach([OVN_MONITOR_ALL], [yes, no], [$1
+])])])])])
diff --git a/tests/ovs-macros.at b/tests/ovs-macros.at
index 94dffa994..df4266d1f 100644
--- a/tests/ovs-macros.at
+++ b/tests/ovs-macros.at
@@ -9,7 +9,7 @@ dnl - If NORTHD_TYPE is defined, then append it to the test 
name and
 dnl   set it as a shell variable as well.
 m4_rename([AT_SETUP], [OVS_AT_SETUP])
 m4_define([AT_SETUP],
-  [OVS_AT_SETUP($@[]m4_ifdef([NORTHD_TYPE], [ -- 
NORTHD_TYPE])[]m4_ifdef([NORTHD_USE_DP_GROUPS], [ -- 
dp-groups=NORTHD_USE_DP_GROUPS])[]m4_ifdef([NORTHD_USE_PARALLELIZATION], [ -- 
parallelization=NORTHD_USE_PARALLELIZATION]))
+  [OVS_AT_SETUP($@[]m4_ifdef([NORTHD_TYPE], [ -- 
NORTHD_TYPE])[]m4_ifdef([NORTHD_USE_DP_GROUPS], [ -- 
dp-groups=NORTHD_USE_DP_GROUPS])[]m4_ifdef([NORTHD_USE_PARALLELIZATION], [ -- 
parallelization=NORTHD_USE_PARALLELIZATION])[]m4_ifdef([OVN_MONITOR_ALL], [ -- 
ovn_monitor_all=OVN_MONITOR_ALL]))
 m4_ifdef([NORTHD_TYPE], [[NORTHD_TYPE]=NORTHD_TYPE
 ])dnl
 m4_ifdef([NORTHD_USE_DP_GROUPS], [[NORTHD_USE_DP_GROUPS]=NORTHD_USE_DP_GROUPS
@@ -18,6 +18,8 @@ m4_ifdef([NORTHD_USE_PARALLELIZATION], 
[[NORTHD_USE_PARALLELIZATION]=NORTHD_USE_
 ])dnl
 m4_ifdef([NORTHD_DUMMY_NUMA], [[NORTHD_DUMMY_NUMA]=NORTHD_DUMMY_NUMA
 ])dnl
+m4_ifdef([OVN_MONITOR_ALL], [[OVN_MONITOR_ALL]=OVN_MONITOR_ALL
+])dnl
 ovs_init
 ])
 
-- 
2.34.1

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


Re: [ovs-dev] [PATCH ovn v2] OVN-CI: Add test cases with monitor-all enabled.

2022-06-23 Thread Mohammad Heib

Hi Dumitru,

thank you for reviewing this patch

On 6/8/22 12:25, Dumitru Ceara wrote:

On 5/31/22 11:33, Mohammad Heib wrote:

currently ovn ci only has one test case with the option
ovn-monitor-all enabled, this patch will add one more
execution with option ovn-monitor-all=true for each test case that
are wrapped by OVN_FOR_EACH_NORTHD macro.

This will more or less double the number of test cases.
It is possible to select a reduce set of test cases using -k "keywords".
Keyword such as
 dp-groups=yes
 dp-groups=no
 parallelization=yes
 parallelization=no
 ovn-northd
 ovn-northd-ddlog
 ovn_monitor_all=yes
can be used to select a range of tests, as title is searched as well.

For instance, to run ovn-monitor-all tests, with dp-groups enabled and ddlog 
disabled:
 make check TESTSUITEFLAGS="-k 
dp-groups=yes,ovn_monitor_all=yes,\!ovn-northd-ddlog"

Signed-off-by: Mohammad Heib
---

Hi Mohammad,

Thanks for working on this, we were really missing tests with
conditional monitoring disabled!


  tests/ovn-macros.at | 19 ---
  tests/ovs-macros.at |  4 +++-
  2 files changed, 19 insertions(+), 4 deletions(-)

diff --git a/tests/ovn-macros.at b/tests/ovn-macros.at
index c6f0f6251..7484b32c3 100644
--- a/tests/ovn-macros.at
+++ b/tests/ovn-macros.at
@@ -323,6 +323,19 @@ ovn_az_attach() {
  -- --may-exist add-br br-int \
  -- set bridge br-int fail-mode=secure 
other-config:disable-in-band=true \
  || return 1
+
+# currently this is the optimal place to add the ovn-monitor-all=true 
option,
+# this can be implemented in a different way by redefining the sim-add 
function
+# to add the ovn-related external-ids when we add a new simulated node via 
sim-add.
+#
+# wait one sec to make sure that the ovn notice and update it configuration
+# according to the new option.
+#
+if test X$OVN_MONITOR_ALL = Xyes; then
+ovs-vsctl set open . external_ids:ovn-monitor-all=true
+sleep 1
+fi
+

I think we can avoid the "sleep 1" if we just do this in the same
transaction as ovn-remote (just above).



updated in v3

  start_daemon ovn-controller --enable-dummy-vif-plug || return 1
  }
  
@@ -751,19 +764,19 @@ m4_define([OVN_FOR_EACH_NORTHD],

[m4_foreach([NORTHD_TYPE], [ovn-northd, ovn-northd-ddlog],
   [m4_foreach([NORTHD_USE_DP_GROUPS], [yes, no],
 [m4_foreach([NORTHD_USE_PARALLELIZATION], [yes, no], [$1
-])])])])
+]) m4_foreach([OVN_MONITOR_ALL], [yes], [$1])])])])

Maybe I misunderstood the goal but this doesn't seem to generate
all possible combinations, e.g.:
i actually tried to save some unit execution time via not executing 
parallelization with ovn_monitor_all
just to save execution time but i agree it's a bit confusing so i 
applied your suggestion to v3 
<https://patchwork.ozlabs.org/project/ovn/patch/20220623110239.2973854-1-mh...@redhat.com/>.


$ make check TESTSUITEFLAGS="-l" | grep 'IP relocation using GARP request'
  291: ovn.at:4906IP relocation using GARP request -- ovn-northd -- 
dp-groups=yes -- parallelization=yes
  292: ovn.at:4906IP relocation using GARP request -- ovn-northd -- 
dp-groups=yes -- parallelization=no
  293: ovn.at:4906IP relocation using GARP request -- ovn-northd -- 
dp-groups=yes -- ovn_monitor_all=yes
  294: ovn.at:4906IP relocation using GARP request -- ovn-northd -- 
dp-groups=no -- parallelization=yes
  295: ovn.at:4906IP relocation using GARP request -- ovn-northd -- 
dp-groups=no -- parallelization=no
  296: ovn.at:4906IP relocation using GARP request -- ovn-northd -- 
dp-groups=no -- ovn_monitor_all=yes
  297: ovn.at:4906IP relocation using GARP request -- ovn-northd-ddlog 
-- dp-groups=yes -- parallelization=yes
  298: ovn.at:4906IP relocation using GARP request -- ovn-northd-ddlog 
-- dp-groups=yes -- parallelization=no
  299: ovn.at:4906IP relocation using GARP request -- ovn-northd-ddlog 
-- dp-groups=yes -- ovn_monitor_all=yes
  300: ovn.at:4906IP relocation using GARP request -- ovn-northd-ddlog 
-- dp-groups=no -- parallelization=yes
  301: ovn.at:4906IP relocation using GARP request -- ovn-northd-ddlog 
-- dp-groups=no -- parallelization=no
  302: ovn.at:4906IP relocation using GARP request -- ovn-northd-ddlog 
-- dp-groups=no -- ovn_monitor_all=yes

It seems to me we're missing:
- dp-groups=yes, parallelization=yes, ovn_monitor_all=yes

I think this should be:

# Defines a versions of a test with all combinations of northd and
# datapath groups.
m4_define([OVN_FOR_EACH_NORTHD],
   [m4_foreach([NORTHD_TYPE], [ovn-northd, ovn-northd-ddlog],
  [m4_foreach([NORTHD_USE_DP_GROUPS], [yes, no],
[m4_foreach([NORTHD_USE_PARALLELIZATION], [yes, no],
   [m4_foreach([OVN_MONITOR_ALL], [yes, no], [$1
])])])])])

Also, related, I sent an RF

[ovs-dev] [PATCH ovn v3]OVN-CI: Add test cases with monitor-all enabled.

2022-06-23 Thread Mohammad Heib
currently ovn ci only has one test case with the option
ovn-monitor-all enabled, this patch will add one more
execution with option ovn-monitor-all=true for each test case that
are wrapped by OVN_FOR_EACH_NORTHD macro.

This will more or less double the number of test cases.
It is possible to select a reduce set of test cases using -k "keywords".
Keyword such as
dp-groups=yes
dp-groups=no
parallelization=yes
parallelization=no
ovn-northd
ovn-northd-ddlog
ovn_monitor_all=yes
can be used to select a range of tests, as title is searched as well.

For instance, to run ovn-monitor-all tests, with dp-groups enabled and ddlog 
disabled:
make check TESTSUITEFLAGS="-k 
dp-groups=yes,ovn_monitor_all=yes,\!ovn-northd-ddlog"

Signed-off-by: Mohammad Heib 
---
 tests/ovn-macros.at | 18 ++
 tests/ovs-macros.at |  4 +++-
 2 files changed, 17 insertions(+), 5 deletions(-)

diff --git a/tests/ovn-macros.at b/tests/ovn-macros.at
index 335f9158c..1858281c6 100644
--- a/tests/ovn-macros.at
+++ b/tests/ovn-macros.at
@@ -323,6 +323,18 @@ ovn_az_attach() {
 -- --may-exist add-br br-int \
 -- set bridge br-int fail-mode=secure 
other-config:disable-in-band=true \
 || return 1
+
+# currently this is the optimal place to add the ovn-monitor-all=true 
option,
+# this can be implemented in a different way by redefining the sim-add 
function
+# to add the ovn-related external-ids when we add a new simulated node via 
sim-add.
+#
+# wait one sec to make sure that the ovn notice and update it configuration
+# according to the new option.
+#
+if test X$OVN_MONITOR_ALL = Xyes; then
+ovs-vsctl set open . external_ids:ovn-monitor-all=true
+fi
+
 start_daemon ovn-controller --enable-dummy-vif-plug || return 1
 }
 
@@ -750,12 +762,10 @@ m4_define([OVN_POPULATE_ARP], 
[AT_CHECK(ovn_populate_arp__, [0], [ignore])])
 m4_define([OVN_FOR_EACH_NORTHD],
   [m4_foreach([NORTHD_TYPE], [ovn-northd],
  [m4_foreach([NORTHD_USE_DP_GROUPS], [yes, no],
-   [m4_foreach([NORTHD_USE_PARALLELIZATION], [yes, no], [$1
-])])])])
+   [m4_foreach([NORTHD_USE_PARALLELIZATION], [yes, no], 
[m4_foreach([OVN_MONITOR_ALL], [yes, no], [$1])])])])])
 
 # Some tests aren't prepared for dp groups to be enabled.
 m4_define([OVN_FOR_EACH_NORTHD_WITHOUT_DP_GROUPS],
   [m4_foreach([NORTHD_TYPE], [ovn-northd],
  [m4_foreach([NORTHD_USE_DP_GROUPS], [no],
-   [m4_foreach([NORTHD_USE_PARALLELIZATION], [yes, no], [$1
-])])])])
+   [m4_foreach([NORTHD_USE_PARALLELIZATION], [yes, no], 
[m4_foreach([OVN_MONITOR_ALL], [yes, no], [$1])])])])])
diff --git a/tests/ovs-macros.at b/tests/ovs-macros.at
index 94dffa994..df4266d1f 100644
--- a/tests/ovs-macros.at
+++ b/tests/ovs-macros.at
@@ -9,7 +9,7 @@ dnl - If NORTHD_TYPE is defined, then append it to the test 
name and
 dnl   set it as a shell variable as well.
 m4_rename([AT_SETUP], [OVS_AT_SETUP])
 m4_define([AT_SETUP],
-  [OVS_AT_SETUP($@[]m4_ifdef([NORTHD_TYPE], [ -- 
NORTHD_TYPE])[]m4_ifdef([NORTHD_USE_DP_GROUPS], [ -- 
dp-groups=NORTHD_USE_DP_GROUPS])[]m4_ifdef([NORTHD_USE_PARALLELIZATION], [ -- 
parallelization=NORTHD_USE_PARALLELIZATION]))
+  [OVS_AT_SETUP($@[]m4_ifdef([NORTHD_TYPE], [ -- 
NORTHD_TYPE])[]m4_ifdef([NORTHD_USE_DP_GROUPS], [ -- 
dp-groups=NORTHD_USE_DP_GROUPS])[]m4_ifdef([NORTHD_USE_PARALLELIZATION], [ -- 
parallelization=NORTHD_USE_PARALLELIZATION])[]m4_ifdef([OVN_MONITOR_ALL], [ -- 
ovn_monitor_all=OVN_MONITOR_ALL]))
 m4_ifdef([NORTHD_TYPE], [[NORTHD_TYPE]=NORTHD_TYPE
 ])dnl
 m4_ifdef([NORTHD_USE_DP_GROUPS], [[NORTHD_USE_DP_GROUPS]=NORTHD_USE_DP_GROUPS
@@ -18,6 +18,8 @@ m4_ifdef([NORTHD_USE_PARALLELIZATION], 
[[NORTHD_USE_PARALLELIZATION]=NORTHD_USE_
 ])dnl
 m4_ifdef([NORTHD_DUMMY_NUMA], [[NORTHD_DUMMY_NUMA]=NORTHD_DUMMY_NUMA
 ])dnl
+m4_ifdef([OVN_MONITOR_ALL], [[OVN_MONITOR_ALL]=OVN_MONITOR_ALL
+])dnl
 ovs_init
 ])
 
-- 
2.34.1

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


Re: [ovs-dev] [PATCH ovn] OVN-CI: remove ddlog test cases.

2022-06-09 Thread Mohammad Heib

Hi Dumitru,

thank you for reviewing this patch.

On 5/30/22 18:50, Dumitru Ceara wrote:

On 5/30/22 10:28, Mohammad Heib wrote:

currently there is no new changes applied to the ddlog code base
in ovn and we keep skipping ddlog test cases in our ci runs which leads
to so many skips lines printed to the ci logs and that cause us to miss
some tests cases that were skipped because of missing packages or any other 
reason.

This patch will remove ddlog test cases from the OVN-CI,
which will give us more clear ci output and less execution time.

Signed-off-by: Mohammad Heib
---

Hi Mohammad,

Thanks for the patch!

I wonder if we should rebase
https://patchwork.ozlabs.org/project/ovn/patch/20211007194649.4014965-1-...@ovn.org/
instead.

In any case, for your patch specifically, I think we can also update the
comment for test "ovn -- NAT and Load Balancer flows" (and wrap the test
in OVN_FOR_EACH_NORTHD()).
i updated the code and removed the ddlog related code from almost all 
the unit tests, still have two places


that mentioning ddlog i will remove in a future patch.

v2.
<https://patchwork.ozlabs.org/project/ovn/patch/20220609122755.961288-1-mh...@redhat.com/>


thanks



A few other tests mention ddlog in the comments but will now never be
run with ovn-northd-ddlog.  We might as well update those comments too.


  tests/ovn-macros.at | 11 +++
  tests/ovn.at|  3 ---
  tests/ovs-macros.at |  4 
  3 files changed, 3 insertions(+), 15 deletions(-)

diff --git a/tests/ovn-macros.at b/tests/ovn-macros.at
index c6f0f6251..df3f35554 100644
--- a/tests/ovn-macros.at
+++ b/tests/ovn-macros.at
@@ -748,22 +748,17 @@ m4_define([OVN_POPULATE_ARP], 
[AT_CHECK(ovn_populate_arp__, [0], [ignore])])
  # Defines a versions of a test with all combinations of northd and
  # datapath groups.
  m4_define([OVN_FOR_EACH_NORTHD],
-  [m4_foreach([NORTHD_TYPE], [ovn-northd, ovn-northd-ddlog],
+  [m4_foreach([NORTHD_TYPE], [ovn-northd],
   [m4_foreach([NORTHD_USE_DP_GROUPS], [yes, no],
 [m4_foreach([NORTHD_USE_PARALLELIZATION], [yes, no], [$1
  ])])])])
  
  # Some tests aren't prepared for dp groups to be enabled.

  m4_define([OVN_FOR_EACH_NORTHD_WITHOUT_DP_GROUPS],
-  [m4_foreach([NORTHD_TYPE], [ovn-northd, ovn-northd-ddlog],
+  [m4_foreach([NORTHD_TYPE], [ovn-northd],
   [m4_foreach([NORTHD_USE_DP_GROUPS], [no],
 [m4_foreach([NORTHD_USE_PARALLELIZATION], [yes, no], [$1
  ])])])])
  
  # Some tests aren't prepared for ddlog to be enabled.

-m4_define([OVN_FOR_EACH_NORTHD_WITHOUT_DDLOG],
-  [m4_foreach([NORTHD_TYPE], [ovn-northd],
- [m4_foreach([NORTHD_USE_DP_GROUPS], [yes, no],
-   [m4_foreach([NORTHD_USE_PARALLELIZATION], [yes, no], [$1
-])])])])
-
+m4_define([OVN_FOR_EACH_NORTHD_WITHOUT_DDLOG], [OVN_FOR_EACH_NORTHD($@)])

As far as I can tell there are only two places where this macro is used.
I think we can just remove it and update the two callers.

Thanks,
Dumitru


diff --git a/tests/ovn.at b/tests/ovn.at
index 4461b840e..1dcd82762 100644
--- a/tests/ovn.at
+++ b/tests/ovn.at
@@ -22993,9 +22993,6 @@ AT_CLEANUP
  OVN_FOR_EACH_NORTHD([
  AT_SETUP([interconnection])
  
-dnl This test has problems with ovn-northd-ddlog.

-AT_SKIP_IF([test NORTHD_TYPE = ovn-northd-ddlog && test "$RUN_ANYWAY" != yes])
-
  ovn_init_ic_db
  n_az=5
  n_ts=5
diff --git a/tests/ovs-macros.at b/tests/ovs-macros.at
index 0482b7f5b..dc3f34dc9 100644
--- a/tests/ovs-macros.at
+++ b/tests/ovs-macros.at
@@ -7,7 +7,6 @@ dnl Make AT_SETUP automatically do some things for us:
  dnl - Run the ovs_init() shell function as the first step in every test.
  dnl - If NORTHD_TYPE is defined, then append it to the test name and
  dnl   set it as a shell variable as well.
-dnl - Skip the test if it's for ovn-northd-ddlog but it didn't get built.
  m4_rename([AT_SETUP], [OVS_AT_SETUP])
  m4_define([AT_SETUP],
[OVS_AT_SETUP($@[]m4_ifdef([NORTHD_TYPE], [ -- 
NORTHD_TYPE])[]m4_ifdef([NORTHD_USE_DP_GROUPS], [ -- 
dp-groups=NORTHD_USE_DP_GROUPS])[]m4_ifdef([NORTHD_USE_PARALLELIZATION], [ -- 
parallelization=NORTHD_USE_PARALLELIZATION]))
@@ -19,9 +18,6 @@ m4_ifdef([NORTHD_USE_PARALLELIZATION], 
[[NORTHD_USE_PARALLELIZATION]=NORTHD_USE_
  ])dnl
  m4_ifdef([NORTHD_DUMMY_NUMA], [[NORTHD_DUMMY_NUMA]=NORTHD_DUMMY_NUMA
  ])dnl
-m4_if(NORTHD_TYPE, [ovn-northd-ddlog], [dnl
-AT_SKIP_IF([test $TEST_DDLOG = no])
-])dnl
  ovs_init
  ])
  

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


[ovs-dev] [ovn patch v2 ]OVN-CI: remove ddlog test cases.

2022-06-09 Thread Mohammad Heib
currently there is no new changes applied to the ddlog code base
in ovn and we keep skipping ddlog test cases in our ci runs which leads
to so many skips lines printed to the ci logs and that cause us to miss
some tests cases that were skipped because of missing packages or any other 
reason.

This patch will remove ddlog test cases from the OVN-CI,
which will give us more clear ci output and less execution time.

Signed-off-by: Mohammad Heib 
---
 tests/atlocal.in|  7 ---
 tests/ovn-macros.at | 12 ++--
 tests/ovn-northd.at | 25 ++---
 tests/ovn.at|  6 --
 tests/ovs-macros.at |  4 
 5 files changed, 8 insertions(+), 46 deletions(-)

diff --git a/tests/atlocal.in b/tests/atlocal.in
index d2edea4ea..b3a011f41 100644
--- a/tests/atlocal.in
+++ b/tests/atlocal.in
@@ -218,10 +218,3 @@ export ASAN_OPTIONS
 # for the build.
 
UBSAN_OPTIONS=print_stacktrace=1:halt_on_error=true:log_path=ubsan:$UBSAN_OPTIONS
 export UBSAN_OPTIONS
-
-# Check whether we should run ddlog tests.
-if test '@DDLOGLIBDIR@' != no; then
-TEST_DDLOG="yes"
-else
-TEST_DDLOG="no"
-fi
diff --git a/tests/ovn-macros.at b/tests/ovn-macros.at
index c6f0f6251..335f9158c 100644
--- a/tests/ovn-macros.at
+++ b/tests/ovn-macros.at
@@ -748,22 +748,14 @@ m4_define([OVN_POPULATE_ARP], 
[AT_CHECK(ovn_populate_arp__, [0], [ignore])])
 # Defines a versions of a test with all combinations of northd and
 # datapath groups.
 m4_define([OVN_FOR_EACH_NORTHD],
-  [m4_foreach([NORTHD_TYPE], [ovn-northd, ovn-northd-ddlog],
+  [m4_foreach([NORTHD_TYPE], [ovn-northd],
  [m4_foreach([NORTHD_USE_DP_GROUPS], [yes, no],
[m4_foreach([NORTHD_USE_PARALLELIZATION], [yes, no], [$1
 ])])])])
 
 # Some tests aren't prepared for dp groups to be enabled.
 m4_define([OVN_FOR_EACH_NORTHD_WITHOUT_DP_GROUPS],
-  [m4_foreach([NORTHD_TYPE], [ovn-northd, ovn-northd-ddlog],
- [m4_foreach([NORTHD_USE_DP_GROUPS], [no],
-   [m4_foreach([NORTHD_USE_PARALLELIZATION], [yes, no], [$1
-])])])])
-
-# Some tests aren't prepared for ddlog to be enabled.
-m4_define([OVN_FOR_EACH_NORTHD_WITHOUT_DDLOG],
   [m4_foreach([NORTHD_TYPE], [ovn-northd],
- [m4_foreach([NORTHD_USE_DP_GROUPS], [yes, no],
+ [m4_foreach([NORTHD_USE_DP_GROUPS], [no],
[m4_foreach([NORTHD_USE_PARALLELIZATION], [yes, no], [$1
 ])])])])
-
diff --git a/tests/ovn-northd.at b/tests/ovn-northd.at
index a94a7d441..e7b535cab 100644
--- a/tests/ovn-northd.at
+++ b/tests/ovn-northd.at
@@ -780,10 +780,6 @@ check_row_count Datapath_Binding 1
 check_row_count Logical_Flow $lf
 
 # Now re-enable the nbdb connection and observe ovn-northd catch up.
-#
-# It's important to check both Datapath_Binding and Logical_Flow because
-# ovn-northd-ddlog implements them in different ways that might go wrong
-# differently on reconnection.
 check as ovn-nb ovs-appctl -t ovsdb-server ovsdb-server/add-remote "$conn"
 wait_row_count Datapath_Binding 2
 wait_row_count Logical_Flow $(expr 2 \* $lf)
@@ -817,9 +813,7 @@ OVN_SB_DB=${conn2#p} check_row_count Logical_Flow $lf
 
 # Now re-enable the sbdb connection and observe ovn-northd catch up.
 #
-# It's important to check both Datapath_Binding and Logical_Flow because
-# ovn-northd-ddlog implements them in different ways that might go wrong
-# differently on reconnection.
+# It's important to check both Datapath_Binding and Logical_Flow.
 check as ovn-sb ovs-appctl -t ovsdb-server ovsdb-server/add-remote "$conn"
 wait_row_count Datapath_Binding 2
 wait_row_count Logical_Flow $(expr 2 \* $lf)
@@ -2161,10 +2155,8 @@ template_band=$(fetch_column nb:meter bands 
name=meter_me)
 check ovn-nbctl --wait=sb set meter_band $template_band rate=123
 AS_BOX([Make sure that every Meter_Band has the right rate.])
 # ovn-northd creates 4 identical Meter_Band rows, all identical;
-# ovn-northd-ddlog creates just 1.  It doesn't matter, they work just
-# as well.)
 n_meter_bands=$(count_rows meter_band)
-AT_FAIL_IF([test "$n_meter_bands" != 1 && test "$n_meter_bands" != 4])
+AT_FAIL_IF([test "$n_meter_bands" != 4])
 check_row_count meter_band $n_meter_bands rate=123
 
 AS_BOX([Check meter in logical flows for acl logs])
@@ -4419,13 +4411,7 @@ AT_CHECK([grep -w "ls_in_dhcp_options" sw0flows | sort | 
sed 's/table=../table=?
 AT_CLEANUP
 ])
 
-# XXX This test currently only runs for northd.c. The test fails
-# with ovn-northd-ddlog because of the section where 2 HA_Chassis_Groups
-# are used by 2 routers. For some reason, this causes ovn-northd-ddlog
-# to stop processing new changes to the northbound database and to
-# seemingly infinitely loop. This issue has been reported, but there is
-# currently no fix for it. Once this issue is fixed, we can run this
-# test for both C and DDLog versions of northd.
+OVN_FOR_EACH_NORTHD([
 AT_SETUP([ovn -- NAT and Load Balancer flows])
 
 # Determine if expected flows are present. The only parameter t

[ovs-dev] [PATCH ovn v2] OVN-CI: Add test cases with monitor-all enabled.

2022-05-31 Thread Mohammad Heib
currently ovn ci only has one test case with the option
ovn-monitor-all enabled, this patch will add one more
execution with option ovn-monitor-all=true for each test case that
are wrapped by OVN_FOR_EACH_NORTHD macro.

This will more or less double the number of test cases.
It is possible to select a reduce set of test cases using -k "keywords".
Keyword such as
dp-groups=yes
dp-groups=no
parallelization=yes
parallelization=no
ovn-northd
ovn-northd-ddlog
ovn_monitor_all=yes
can be used to select a range of tests, as title is searched as well.

For instance, to run ovn-monitor-all tests, with dp-groups enabled and ddlog 
disabled:
make check TESTSUITEFLAGS="-k 
dp-groups=yes,ovn_monitor_all=yes,\!ovn-northd-ddlog"

Signed-off-by: Mohammad Heib 
---
 tests/ovn-macros.at | 19 ---
 tests/ovs-macros.at |  4 +++-
 2 files changed, 19 insertions(+), 4 deletions(-)

diff --git a/tests/ovn-macros.at b/tests/ovn-macros.at
index c6f0f6251..7484b32c3 100644
--- a/tests/ovn-macros.at
+++ b/tests/ovn-macros.at
@@ -323,6 +323,19 @@ ovn_az_attach() {
 -- --may-exist add-br br-int \
 -- set bridge br-int fail-mode=secure 
other-config:disable-in-band=true \
 || return 1
+
+# currently this is the optimal place to add the ovn-monitor-all=true 
option,
+# this can be implemented in a different way by redefining the sim-add 
function
+# to add the ovn-related external-ids when we add a new simulated node via 
sim-add.
+#
+# wait one sec to make sure that the ovn notice and update it configuration
+# according to the new option.
+#
+if test X$OVN_MONITOR_ALL = Xyes; then
+ovs-vsctl set open . external_ids:ovn-monitor-all=true
+sleep 1
+fi
+
 start_daemon ovn-controller --enable-dummy-vif-plug || return 1
 }
 
@@ -751,19 +764,19 @@ m4_define([OVN_FOR_EACH_NORTHD],
   [m4_foreach([NORTHD_TYPE], [ovn-northd, ovn-northd-ddlog],
  [m4_foreach([NORTHD_USE_DP_GROUPS], [yes, no],
[m4_foreach([NORTHD_USE_PARALLELIZATION], [yes, no], [$1
-])])])])
+]) m4_foreach([OVN_MONITOR_ALL], [yes], [$1])])])])
 
 # Some tests aren't prepared for dp groups to be enabled.
 m4_define([OVN_FOR_EACH_NORTHD_WITHOUT_DP_GROUPS],
   [m4_foreach([NORTHD_TYPE], [ovn-northd, ovn-northd-ddlog],
  [m4_foreach([NORTHD_USE_DP_GROUPS], [no],
[m4_foreach([NORTHD_USE_PARALLELIZATION], [yes, no], [$1
-])])])])
+])m4_foreach([OVN_MONITOR_ALL], [yes], [$1])])])])
 
 # Some tests aren't prepared for ddlog to be enabled.
 m4_define([OVN_FOR_EACH_NORTHD_WITHOUT_DDLOG],
   [m4_foreach([NORTHD_TYPE], [ovn-northd],
  [m4_foreach([NORTHD_USE_DP_GROUPS], [yes, no],
[m4_foreach([NORTHD_USE_PARALLELIZATION], [yes, no], [$1
-])])])])
+])m4_foreach([OVN_MONITOR_ALL], [yes], [$1])])])])
 
diff --git a/tests/ovs-macros.at b/tests/ovs-macros.at
index 0482b7f5b..5d6c3ada2 100644
--- a/tests/ovs-macros.at
+++ b/tests/ovs-macros.at
@@ -10,7 +10,7 @@ dnl   set it as a shell variable as well.
 dnl - Skip the test if it's for ovn-northd-ddlog but it didn't get built.
 m4_rename([AT_SETUP], [OVS_AT_SETUP])
 m4_define([AT_SETUP],
-  [OVS_AT_SETUP($@[]m4_ifdef([NORTHD_TYPE], [ -- 
NORTHD_TYPE])[]m4_ifdef([NORTHD_USE_DP_GROUPS], [ -- 
dp-groups=NORTHD_USE_DP_GROUPS])[]m4_ifdef([NORTHD_USE_PARALLELIZATION], [ -- 
parallelization=NORTHD_USE_PARALLELIZATION]))
+  [OVS_AT_SETUP($@[]m4_ifdef([NORTHD_TYPE], [ -- 
NORTHD_TYPE])[]m4_ifdef([NORTHD_USE_DP_GROUPS], [ -- 
dp-groups=NORTHD_USE_DP_GROUPS])[]m4_ifdef([NORTHD_USE_PARALLELIZATION], [ -- 
parallelization=NORTHD_USE_PARALLELIZATION])[]m4_ifdef([OVN_MONITOR_ALL], [ -- 
ovn_monitor_all=OVN_MONITOR_ALL]))
 m4_ifdef([NORTHD_TYPE], [[NORTHD_TYPE]=NORTHD_TYPE
 ])dnl
 m4_ifdef([NORTHD_USE_DP_GROUPS], [[NORTHD_USE_DP_GROUPS]=NORTHD_USE_DP_GROUPS
@@ -19,6 +19,8 @@ m4_ifdef([NORTHD_USE_PARALLELIZATION], 
[[NORTHD_USE_PARALLELIZATION]=NORTHD_USE_
 ])dnl
 m4_ifdef([NORTHD_DUMMY_NUMA], [[NORTHD_DUMMY_NUMA]=NORTHD_DUMMY_NUMA
 ])dnl
+m4_ifdef([OVN_MONITOR_ALL], [[OVN_MONITOR_ALL]=OVN_MONITOR_ALL
+])dnl
 m4_if(NORTHD_TYPE, [ovn-northd-ddlog], [dnl
 AT_SKIP_IF([test $TEST_DDLOG = no])
 ])dnl
-- 
2.34.1

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


[ovs-dev] [PATCH ovn] OVN-CI: Add test cases with monitor-all enabled.

2022-05-31 Thread Mohammad Heib
currently ovn ci only has one test case with the option
ovn-monitor-all enabled, this patch will add one more
execution with option ovn-monitor-all=true for each test case that
are wrapped by OVN_FOR_EACH_NORTHD macro.

This will more or less double the number of test cases.
It is possible to select a reduce set of test cases using -k "keywords".
Keyword such as
dp-groups=yes
dp-groups=no
parallelization=yes
parallelization=no
ovn-northd
ovn-northd-ddlog
ovn_monitor_all=yes
can be used to select a range of tests, as title is searched as well.

For instance, to run ovn-parallelization tests, with dp-groups enabled and 
ddlog disabled:
make check TESTSUITEFLAGS="-k 
dp-groups=yes,ovn_monitor_all=yes,\!ovn-northd-ddlog"

Signed-off-by: Mohammad Heib 
---
 tests/ovn-macros.at | 19 ---
 tests/ovs-macros.at |  4 +++-
 2 files changed, 19 insertions(+), 4 deletions(-)

diff --git a/tests/ovn-macros.at b/tests/ovn-macros.at
index c6f0f6251..7484b32c3 100644
--- a/tests/ovn-macros.at
+++ b/tests/ovn-macros.at
@@ -323,6 +323,19 @@ ovn_az_attach() {
 -- --may-exist add-br br-int \
 -- set bridge br-int fail-mode=secure 
other-config:disable-in-band=true \
 || return 1
+
+# currently this is the optimal place to add the ovn-monitor-all=true 
option,
+# this can be implemented in a different way by redefining the sim-add 
function
+# to add the ovn-related external-ids when we add a new simulated node via 
sim-add.
+#
+# wait one sec to make sure that the ovn notice and update it configuration
+# according to the new option.
+#
+if test X$OVN_MONITOR_ALL = Xyes; then
+ovs-vsctl set open . external_ids:ovn-monitor-all=true
+sleep 1
+fi
+
 start_daemon ovn-controller --enable-dummy-vif-plug || return 1
 }
 
@@ -751,19 +764,19 @@ m4_define([OVN_FOR_EACH_NORTHD],
   [m4_foreach([NORTHD_TYPE], [ovn-northd, ovn-northd-ddlog],
  [m4_foreach([NORTHD_USE_DP_GROUPS], [yes, no],
[m4_foreach([NORTHD_USE_PARALLELIZATION], [yes, no], [$1
-])])])])
+]) m4_foreach([OVN_MONITOR_ALL], [yes], [$1])])])])
 
 # Some tests aren't prepared for dp groups to be enabled.
 m4_define([OVN_FOR_EACH_NORTHD_WITHOUT_DP_GROUPS],
   [m4_foreach([NORTHD_TYPE], [ovn-northd, ovn-northd-ddlog],
  [m4_foreach([NORTHD_USE_DP_GROUPS], [no],
[m4_foreach([NORTHD_USE_PARALLELIZATION], [yes, no], [$1
-])])])])
+])m4_foreach([OVN_MONITOR_ALL], [yes], [$1])])])])
 
 # Some tests aren't prepared for ddlog to be enabled.
 m4_define([OVN_FOR_EACH_NORTHD_WITHOUT_DDLOG],
   [m4_foreach([NORTHD_TYPE], [ovn-northd],
  [m4_foreach([NORTHD_USE_DP_GROUPS], [yes, no],
[m4_foreach([NORTHD_USE_PARALLELIZATION], [yes, no], [$1
-])])])])
+])m4_foreach([OVN_MONITOR_ALL], [yes], [$1])])])])
 
diff --git a/tests/ovs-macros.at b/tests/ovs-macros.at
index 0482b7f5b..5d6c3ada2 100644
--- a/tests/ovs-macros.at
+++ b/tests/ovs-macros.at
@@ -10,7 +10,7 @@ dnl   set it as a shell variable as well.
 dnl - Skip the test if it's for ovn-northd-ddlog but it didn't get built.
 m4_rename([AT_SETUP], [OVS_AT_SETUP])
 m4_define([AT_SETUP],
-  [OVS_AT_SETUP($@[]m4_ifdef([NORTHD_TYPE], [ -- 
NORTHD_TYPE])[]m4_ifdef([NORTHD_USE_DP_GROUPS], [ -- 
dp-groups=NORTHD_USE_DP_GROUPS])[]m4_ifdef([NORTHD_USE_PARALLELIZATION], [ -- 
parallelization=NORTHD_USE_PARALLELIZATION]))
+  [OVS_AT_SETUP($@[]m4_ifdef([NORTHD_TYPE], [ -- 
NORTHD_TYPE])[]m4_ifdef([NORTHD_USE_DP_GROUPS], [ -- 
dp-groups=NORTHD_USE_DP_GROUPS])[]m4_ifdef([NORTHD_USE_PARALLELIZATION], [ -- 
parallelization=NORTHD_USE_PARALLELIZATION])[]m4_ifdef([OVN_MONITOR_ALL], [ -- 
ovn_monitor_all=OVN_MONITOR_ALL]))
 m4_ifdef([NORTHD_TYPE], [[NORTHD_TYPE]=NORTHD_TYPE
 ])dnl
 m4_ifdef([NORTHD_USE_DP_GROUPS], [[NORTHD_USE_DP_GROUPS]=NORTHD_USE_DP_GROUPS
@@ -19,6 +19,8 @@ m4_ifdef([NORTHD_USE_PARALLELIZATION], 
[[NORTHD_USE_PARALLELIZATION]=NORTHD_USE_
 ])dnl
 m4_ifdef([NORTHD_DUMMY_NUMA], [[NORTHD_DUMMY_NUMA]=NORTHD_DUMMY_NUMA
 ])dnl
+m4_ifdef([OVN_MONITOR_ALL], [[OVN_MONITOR_ALL]=OVN_MONITOR_ALL
+])dnl
 m4_if(NORTHD_TYPE, [ovn-northd-ddlog], [dnl
 AT_SKIP_IF([test $TEST_DDLOG = no])
 ])dnl
-- 
2.34.1

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


  1   2   >