diff --git a/lib/ovn-util.c b/lib/ovn-util.c index ee5cbcdc3c..9b81989b9b 100644 --- a/lib/ovn-util.c +++ b/lib/ovn-util.c @@ -689,11 +689,17 @@ next_tnlid(uint32_t tnlid, uint32_t min, uint32_t max) return tnlid + 1 <= max ? tnlid + 1 : min; } +static uint32_t +prev_tnlid(uint32_t tnlid, uint32_t min, uint32_t max) +{ + return tnlid - 1 <= min ? tnlid - 1 : max; +} + uint32_t ovn_allocate_tnlid(struct hmap *set, const char *name, uint32_t min, uint32_t max, uint32_t *hint) { - for (uint32_t tnlid = next_tnlid(*hint, min, max); tnlid != *hint; + for (uint32_t tnlid = *hint; tnlid != prev_tnlid(*hint, min, max); tnlid = next_tnlid(tnlid, min, max)) { if (ovn_add_tnlid(set, tnlid)) { *hint = tnlid; diff --git a/northd/northd.c b/northd/northd.c index c568f6360d..ce425b2b1c 100644 --- a/northd/northd.c +++ b/northd/northd.c @@ -1009,7 +1009,7 @@ build_datapaths(struct ovsdb_idl_txn *ovnsb_txn, } /* Assign new tunnel ids where needed. */ - uint32_t hint = 0; + uint32_t hint = OVN_MIN_DP_KEY_LOCAL; LIST_FOR_EACH_SAFE (od, list, &both) { ovn_datapath_allocate_key(sbrec_chassis_table, datapaths, &dp_tnlids, od, &hint); diff --git a/tests/ovn-northd.at b/tests/ovn-northd.at index cd53755b28..174dbacdaf 100644 --- a/tests/ovn-northd.at +++ b/tests/ovn-northd.at @@ -2822,6 +2822,32 @@ AT_CHECK([test $lsp02 = 3 && test $ls1 = 123]) AT_CLEANUP ]) +OVN_FOR_EACH_NORTHD_NO_HV([ +AT_SETUP([check tunnel ids exhaustion]) +ovn_start + +# Create a fake chassis with vxlan encap to lower MAX DP tunnel key to 2^12 +ovn-sbctl \ + --id=@e create encap chassis_name=hv1 ip="192.168.0.1" type="vxlan" \ + -- --id=@c create chassis name=hv1 encaps=@e + +cmd="ovn-nbctl --wait=sb" + +for i in {1..4097..1}; do + cmd="${cmd} -- ls-add lsw-${i}" +done + +eval $cmd + +check_row_count nb:Logical_Switch 4097 +wait_row_count sb:Datapath_Binding 4095 + +OVS_WAIT_UNTIL([grep "all datapath tunnel ids exhausted" northd/ovn-northd.log]) + +AT_CLEANUP +]) + + OVN_FOR_EACH_NORTHD_NO_HV([ AT_SETUP([Logical Flow Datapath Groups]) ovn_start