+sub parse_idmap {
+ my ($idmap, $idformat) = @_;
+
+ return undef if !$idmap;
+
+ my $map = {};
+
+ foreach my $entry (PVE::Tools::split_list($idmap)) {
+ if ($entry eq '1') {
+ $map->{identity} = 1;
+ } elsif ($entry =~ m/^([^:]+):([^:]+)$/) {
+ my ($source, $target) = ($1, $2);
+ eval {
+ check_format($idformat, $source, '');
+ check_format($idformat, $target, '');
+ };
+ die "entry '$entry' contains invalid ID - $@\n" if $@;
+
+ die "duplicate mapping for source '$source'\n"
+ if exists $map->{entries}->{$source};
+
+ $map->{entries}->{$source} = $target;
+ } else {
+ eval {
+ check_format($idformat, $entry);
+ };
+ die "entry '$entry' contains invalid ID - $@\n" if $@;
+
+ die "default target ID can only be provided once\n"
+ if exists $map->{default};
+
+ $map->{default} = $entry;
+ }
+ }
+
+ die "identity mapping cannot be combined with other mappings\n"
+ if $map->{identity} && ($map->{default} || exists $map->{entries});
+
+ return $map;
+}
+
+register_format('storagepair', \&verify_storagepair);
+sub verify_storagepair {
+ my ($storagepair, $noerr) = @_;
+
+ # note: this only checks a single list entry
+ # when using a storagepair-list map, you need to pass the full
+ # parameter to parse_idmap
+ eval { parse_idmap($storagepair, 'pve-storage-id') };
+ if ($@) {
+ return undef if $noerr;
+ die "$@\n";
+ }
+
+ return $storagepair;
+}
+
+register_format('mac-addr', \&pve_verify_mac_addr);
+sub pve_verify_mac_addr {
+ my ($mac_addr, $noerr) = @_;
+
+ # don't allow I/G bit to be set, most of the time it breaks things, see:
+ # https://pve.proxmox.com/pipermail/pve-devel/2019-March/035998.html
+ if ($mac_addr !~ m/^[a-f0-9][02468ace](?::[a-f0-9]{2}){5}$/i) {
+ return undef if $noerr;
+ die "value does not look like a valid unicast MAC address\n";
+ }
+ return $mac_addr;
+
+}
+register_standard_option('mac-addr', {
+ type => 'string',
+ description => 'Unicast MAC address.',
+ verbose_description => 'A common MAC address with the I/G (Individual/Group) bit not set.',
+ format_description => "XX:XX:XX:XX:XX:XX",
+ optional => 1,
+ format => 'mac-addr',
+});
+