From: Dmitry Koshelev <dlkoshe...@cloud.ru>

Hello,

My colleague Dmitry Koshelev resolved an issue in OVN where a crash in northd 
would occur if we attempted to destroy a non-existent ovn_port. We discovered 
this problem during testing.

A test case exists to verify the fix, but since it takes a long time to 
execute, I haven’t included it in the patch. Instead, I’ve mentioned it in the 
description for reference.


AT_SETUP([evosdn-973: 32k limit for number of ports on switch])
AT_KEYWORDS([evosdn])

ovn_start
net_add n1

check as ovn-nb ovs-appctl -t ovsdb-server vlog/set info
check as ovn-sb ovs-appctl -t ovsdb-server vlog/set info
check as northd ovs-appctl -t ovn-northd vlog/set info

check ovn-nbctl ls-add pub

export OVN_NB_DAEMON=$(ovn-nbctl --pidfile --detach)
for i in {1..32800}
do
   mac=$(svp_mac_inc a0:02:f0:00:00:01 $(( $i - 1 )) )
   ip=$(svp_ip_inc 10.0.0.1/29 $(( ($i - 1) * 8 )))
   check ovn-nbctl lsp-add pub lsp_$i
   check ovn-nbctl lsp-set-addresses lsp_$i "$mac $ip"
   check ovn-nbctl lsp-set-enabled lsp_$i enabled
done
check ovn-nbctl --wait=sb sync
kill $(cat $OVN_RUNDIR/ovn-nbctl.pid)
unset OVN_NB_DAEMON

OVS_WAIT_UNTIL([test $(grep -c "all port tunnel ids exhausted" 
northd/ovn-northd.log) -ge 0])

AT_CLEANUP

Signed-off-by: Dmitry Koshelev <dlkoshe...@cloud.ru>

---
 northd/northd.c | 15 +++---
 1 file changed, 12 insertions(+), 3 deletions(-)

diff --git a/northd/northd.c b/northd/northd.c
index 64a7f3f89..c8dbaccfd 100644
--- a/northd/northd.c
+++ b/northd/northd.c
@@ -1291,6 +1294,8 @@ ovn_port_create(struct hmap *ports, const char *key,
 
     op->lflow_ref = lflow_ref_create();
     op->stateful_lflow_ref = lflow_ref_create();
+
+ ovs_list_init(&op->list);
 
     return op;
 }
@@ -4679,6 +4686,7 @@ static bool
 ls_port_init(struct ovn_port *op, struct ovsdb_idl_txn *ovnsb_txn,
              struct ovn_datapath *od,
              const struct sbrec_port_binding *sb,
+ bool *destroyed,
              const struct sbrec_mirror_table *sbrec_mirror_table,
              struct ovsdb_idl_index *sbrec_chassis_by_name,
              struct ovsdb_idl_index *sbrec_chassis_by_hostname)
@@ -4697,6 +4705,9 @@ ls_port_init(struct ovn_port *op, struct ovsdb_idl_txn 
*ovnsb_txn,
     }
     /* Assign new tunnel ids where needed. */
     if (!ovn_port_allocate_key(op)) {
+ if (destroyed) {
+ *destroyed = true;
+ }
         return false;
     }
     /* Create new binding, if needed. */
@@ -4726,9 +4737,12 @@ ls_port_create(struct ovsdb_idl_txn *ovnsb_txn, struct 
hmap *ls_ports,
     struct ovn_port *op = ovn_port_create(ls_ports, key, nbsp, NULL,
                                           NULL);
     hmap_insert(&od->ports, &op->dp_node, hmap_node_hash(&op->key_node));
- if (!ls_port_init(op, ovnsb_txn, od, NULL, sbrec_mirror_table,
+ bool destroyed = false;
+ if (!ls_port_init(op, ovnsb_txn, od, NULL, &destroyed, sbrec_mirror_table,
                       sbrec_chassis_by_name, sbrec_chassis_by_hostname)) {
- ovn_port_destroy(ls_ports, op);
+ if (!destroyed) {
+ ovn_port_destroy(ls_ports, op);
+ }
         return NULL;
     }
 
@@ -4748,7 +4762,7 @@ ls_port_reinit(struct ovn_port *op, struct ovsdb_idl_txn 
*ovnsb_txn,
     op->sb = sb;
     ovn_port_set_nb(op, nbsp, NULL);
     op->primary_port = op->cr_port = NULL;
- return ls_port_init(op, ovnsb_txn, od, sb, sbrec_mirror_table,
+ return ls_port_init(op, ovnsb_txn, od, sb, NULL, sbrec_mirror_table,
                         sbrec_chassis_by_name, sbrec_chassis_by_hostname);
 }

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

Reply via email to