Current code (CfgSubnets add()) just checks same ID and same textual prefix. This is far to be enough both because there are good reasons to have the same prefix and because the textual and loosely checked prefix is used defending only against bad cut & pastes.
The ultimate goal, checking ambiguous / depending over subnet order subnet selection, is clearly unreachable because of subnet guards.
So we can split into two different modes:
a default strict mode where obvious ambiguities raise an error.
a relaxed mode requiring IDs where only duplicated IDs raise an error.
Note subnet selection can be overwritten by a hook (cf the RADIUS hook which optionally does this) so we can consider that in not-default relaxed mode the administrator knows what (s)he does.
Malformed prefixes, e.g., 18.104.22.168/14, will be rejected (i.e. raise an error at parsing). To canonize stored prefixes is an open question (IMHO unneeded when bad formed prefixes are rejected, note it matters more for IPv6...)
Current textual prefix is broken and will be removed.
Easy: add a new global flag false by default.
IDs will be required (i.e. no auto-generation) and will be checked for duplicate. No other checks about duplication will be done.
Keep the duplicate ID check and add some new checks against selection ambiguities:
overlapping prefixes (cf current poolOverlaps) between two unguarded subnets
shared relay info between two unguarded subnets
guarded subnet matching a previous not-guarded subnet (with matching being overlapping prefixes or shared relay info)
should we do something about interfaces? (clearly it can broken most shared-network configs)
Strict mode will be the default so a few ambiguous or badly formed configurations will be rejected.
Well formed not ambiguous configurations will work as in previous releases.