public inbox for pve-devel@lists.proxmox.com
 help / color / mirror / Atom feed
* [pve-devel] SPAM: [PATCH pve-network v2 1/4] vnet: do not skip if no range is defined, ask for allocation inside prefix instead
       [not found] <20241209113158.7343-1-lou.lecrivain@wdz.de>
@ 2024-12-09 11:31 ` Lou Lecrivain via pve-devel
  2024-12-12 13:58   ` Stefan Hanreich
  2024-12-09 11:31 ` [pve-devel] SPAM: [PATCH pve-network v2 2/4] dhcp: always generate dhcp-range for dnsmasq Lou Lecrivain via pve-devel
                   ` (3 subsequent siblings)
  4 siblings, 1 reply; 8+ messages in thread
From: Lou Lecrivain via pve-devel @ 2024-12-09 11:31 UTC (permalink / raw)
  To: pve-devel; +Cc: Lou Lecrivain

[-- Attachment #1: Type: message/rfc822, Size: 4426 bytes --]

From: Lou Lecrivain <lou.lecrivain@wdz.de>
To: pve-devel@lists.proxmox.com
Subject: SPAM: [PATCH pve-network v2 1/4] vnet: do not skip if no range is defined, ask for allocation inside prefix instead
Date: Mon,  9 Dec 2024 12:31:55 +0100
Message-ID: <20241209113158.7343-2-lou.lecrivain@wdz.de>

Signed-off-by: lou lecrivain <lou.lecrivain@wdz.de>
---
 src/PVE/Network/SDN/Vnets.pm | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/src/PVE/Network/SDN/Vnets.pm b/src/PVE/Network/SDN/Vnets.pm
index 45292e3..4e795f2 100644
--- a/src/PVE/Network/SDN/Vnets.pm
+++ b/src/PVE/Network/SDN/Vnets.pm
@@ -118,11 +118,10 @@ sub add_next_free_cidr {
 	    my $network = $subnet->{network};
 
 	    next if Net::IP::ip_get_version($network) != $ipversion || $ips->{$ipversion};
-	    next if !$subnet->{'dhcp-range'};
 	    $subnetcount++;
 
 	    eval {
-		$ip = PVE::Network::SDN::Subnets::add_next_free_ip($zone, $subnetid, $subnet, $hostname, $mac, $vmid, $skipdns, $dhcprange);
+		$ip = PVE::Network::SDN::Subnets::add_next_free_ip($zone, $subnetid, $subnet, $hostname, $mac, $vmid, $skipdns, $subnet->{'dhcp-range'});
 	    };
 	    die $@ if $@;
 
-- 
2.39.5



[-- Attachment #2: Type: text/plain, Size: 160 bytes --]

_______________________________________________
pve-devel mailing list
pve-devel@lists.proxmox.com
https://lists.proxmox.com/cgi-bin/mailman/listinfo/pve-devel

^ permalink raw reply	[flat|nested] 8+ messages in thread

* [pve-devel] SPAM: [PATCH pve-network v2 2/4] dhcp: always generate dhcp-range for dnsmasq
       [not found] <20241209113158.7343-1-lou.lecrivain@wdz.de>
  2024-12-09 11:31 ` [pve-devel] SPAM: [PATCH pve-network v2 1/4] vnet: do not skip if no range is defined, ask for allocation inside prefix instead Lou Lecrivain via pve-devel
@ 2024-12-09 11:31 ` Lou Lecrivain via pve-devel
  2024-12-09 11:31 ` [pve-devel] SPAM: [PATCH pve-network v2 3/4] fix: register details in pve ipam db for add_next_freeip Lou Lecrivain via pve-devel
                   ` (2 subsequent siblings)
  4 siblings, 0 replies; 8+ messages in thread
From: Lou Lecrivain via pve-devel @ 2024-12-09 11:31 UTC (permalink / raw)
  To: pve-devel; +Cc: Lou Lecrivain

[-- Attachment #1: Type: message/rfc822, Size: 5859 bytes --]

From: Lou Lecrivain <lou.lecrivain@wdz.de>
To: pve-devel@lists.proxmox.com
Subject: SPAM: [PATCH pve-network v2 2/4] dhcp: always generate dhcp-range for dnsmasq
Date: Mon,  9 Dec 2024 12:31:56 +0100
Message-ID: <20241209113158.7343-3-lou.lecrivain@wdz.de>

(configure_range is now noop)

Signed-off-by: lou lecrivain <lou.lecrivain@wdz.de>
---
 src/PVE/Network/SDN/Dhcp.pm         |  3 ++-
 src/PVE/Network/SDN/Dhcp/Dnsmasq.pm | 23 ++++++++++-------------
 2 files changed, 12 insertions(+), 14 deletions(-)

diff --git a/src/PVE/Network/SDN/Dhcp.pm b/src/PVE/Network/SDN/Dhcp.pm
index d48de34..3ee18e0 100644
--- a/src/PVE/Network/SDN/Dhcp.pm
+++ b/src/PVE/Network/SDN/Dhcp.pm
@@ -98,11 +98,12 @@ sub regenerate_config {
 		my $subnet_config = $subnets->{$subnet_id};
 		my $dhcp_ranges = PVE::Network::SDN::Subnets::get_dhcp_ranges($subnet_config);
 
+		next if !$dhcp_ranges;
 		my ($zone, $subnet_network, $subnet_mask) = split(/-/, $subnet_id);
 		next if $zone ne $zoneid;
-		next if !$dhcp_ranges;
 
 		eval { $dhcp_plugin->configure_subnet($config, $zoneid, $vnetid, $subnet_config) };
+
 		warn "Could not configure subnet $subnet_id: $@\n" if $@;
 
 		foreach my $dhcp_range (@$dhcp_ranges) {
diff --git a/src/PVE/Network/SDN/Dhcp/Dnsmasq.pm b/src/PVE/Network/SDN/Dhcp/Dnsmasq.pm
index ae52d31..263d24f 100644
--- a/src/PVE/Network/SDN/Dhcp/Dnsmasq.pm
+++ b/src/PVE/Network/SDN/Dhcp/Dnsmasq.pm
@@ -129,6 +129,15 @@ sub configure_subnet {
 
     my $tag = $subnet_config->{id};
 
+    my ($zone, $network, $mask) = split(/-/, $tag);
+
+    if (Net::IP::ip_is_ipv4($network)) {
+	$mask = (2 ** $mask - 1) << (32 - $mask);
+	$mask = join( '.', unpack( "C4", pack( "N", $mask ) ) );
+    }
+
+    push @{$config}, "dhcp-range=set:$tag,$network,static,$mask,infinite";
+
     my $option_string;
     if (ip_is_ipv6($subnet_config->{network})) {
 	$option_string = 'option6';
@@ -139,22 +148,10 @@ sub configure_subnet {
 
     push @{$config}, "dhcp-option=tag:$tag,$option_string:dns-server,$subnet_config->{'dhcp-dns-server'}"
 	if $subnet_config->{'dhcp-dns-server'};
-
 }
 
 sub configure_range {
-    my ($class, $config, $dhcpid, $vnetid, $subnet_config, $range_config) = @_;
-
-    my $tag = $subnet_config->{id};
-
-    my ($zone, $network, $mask) = split(/-/, $tag);
-
-    if (Net::IP::ip_is_ipv4($network)) {
-	$mask = (2 ** $mask - 1) << (32 - $mask);
-	$mask = join( '.', unpack( "C4", pack( "N", $mask ) ) );
-    }
-
-    push @{$config}, "dhcp-range=set:$tag,$network,static,$mask,infinite";
+    # noop, everything is done within configure_subnet
 }
 
 sub configure_vnet {
-- 
2.39.5



[-- Attachment #2: Type: text/plain, Size: 160 bytes --]

_______________________________________________
pve-devel mailing list
pve-devel@lists.proxmox.com
https://lists.proxmox.com/cgi-bin/mailman/listinfo/pve-devel

^ permalink raw reply	[flat|nested] 8+ messages in thread

* [pve-devel] SPAM: [PATCH pve-network v2 3/4] fix: register details in pve ipam db for add_next_freeip
       [not found] <20241209113158.7343-1-lou.lecrivain@wdz.de>
  2024-12-09 11:31 ` [pve-devel] SPAM: [PATCH pve-network v2 1/4] vnet: do not skip if no range is defined, ask for allocation inside prefix instead Lou Lecrivain via pve-devel
  2024-12-09 11:31 ` [pve-devel] SPAM: [PATCH pve-network v2 2/4] dhcp: always generate dhcp-range for dnsmasq Lou Lecrivain via pve-devel
@ 2024-12-09 11:31 ` Lou Lecrivain via pve-devel
  2024-12-09 11:31 ` [pve-devel] SPAM: [PATCH pve-network v2 4/4] update tests following changes to behaviour: - allocating IPs also when prefix-only - PVE IPAM register details for every allocation strategy Lou Lecrivain via pve-devel
       [not found] ` <20241209113158.7343-3-lou.lecrivain@wdz.de>
  4 siblings, 0 replies; 8+ messages in thread
From: Lou Lecrivain via pve-devel @ 2024-12-09 11:31 UTC (permalink / raw)
  To: pve-devel; +Cc: Lou Lecrivain

[-- Attachment #1: Type: message/rfc822, Size: 4180 bytes --]

From: Lou Lecrivain <lou.lecrivain@wdz.de>
To: pve-devel@lists.proxmox.com
Subject: SPAM: [PATCH pve-network v2 3/4] fix: register details in pve ipam db for add_next_freeip
Date: Mon,  9 Dec 2024 12:31:57 +0100
Message-ID: <20241209113158.7343-4-lou.lecrivain@wdz.de>

Signed-off-by: lou lecrivain <lou.lecrivain@wdz.de>
---
 src/PVE/Network/SDN/Ipams/PVEPlugin.pm | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/src/PVE/Network/SDN/Ipams/PVEPlugin.pm b/src/PVE/Network/SDN/Ipams/PVEPlugin.pm
index 742f1b1..c225655 100644
--- a/src/PVE/Network/SDN/Ipams/PVEPlugin.pm
+++ b/src/PVE/Network/SDN/Ipams/PVEPlugin.pm
@@ -196,7 +196,11 @@ sub add_next_freeip {
 
 	die "can't find free ip in subnet '$cidr'\n" if !$freeip;
 
-	$dbsubnet->{ips}->{$freeip} = {};
+	$dbsubnet->{ips}->{$freeip} = {
+	    mac => $mac,
+	    hostname => $hostname,
+	    vmid => $vmid
+	};
 
 	write_db($db);
     });
-- 
2.39.5



[-- Attachment #2: Type: text/plain, Size: 160 bytes --]

_______________________________________________
pve-devel mailing list
pve-devel@lists.proxmox.com
https://lists.proxmox.com/cgi-bin/mailman/listinfo/pve-devel

^ permalink raw reply	[flat|nested] 8+ messages in thread

* [pve-devel] SPAM: [PATCH pve-network v2 4/4] update tests following changes to behaviour: - allocating IPs also when prefix-only - PVE IPAM register details for every allocation strategy
       [not found] <20241209113158.7343-1-lou.lecrivain@wdz.de>
                   ` (2 preceding siblings ...)
  2024-12-09 11:31 ` [pve-devel] SPAM: [PATCH pve-network v2 3/4] fix: register details in pve ipam db for add_next_freeip Lou Lecrivain via pve-devel
@ 2024-12-09 11:31 ` Lou Lecrivain via pve-devel
       [not found] ` <20241209113158.7343-3-lou.lecrivain@wdz.de>
  4 siblings, 0 replies; 8+ messages in thread
From: Lou Lecrivain via pve-devel @ 2024-12-09 11:31 UTC (permalink / raw)
  To: pve-devel; +Cc: Lou Lecrivain

[-- Attachment #1: Type: message/rfc822, Size: 6406 bytes --]

From: Lou Lecrivain <lou.lecrivain@wdz.de>
To: pve-devel@lists.proxmox.com
Subject: SPAM: [PATCH pve-network v2 4/4] update tests following changes to behaviour: - allocating IPs also when prefix-only - PVE IPAM register details for every allocation strategy
Date: Mon,  9 Dec 2024 12:31:58 +0100
Message-ID: <20241209113158.7343-5-lou.lecrivain@wdz.de>

Signed-off-by: lou lecrivain <lou.lecrivain@wdz.de>
---
 src/test/run_test_subnets.pl        | 24 +++++++++++++++++++++---
 src/test/run_test_vnets_blackbox.pl |  6 ++----
 2 files changed, 23 insertions(+), 7 deletions(-)

diff --git a/src/test/run_test_subnets.pl b/src/test/run_test_subnets.pl
index d1af0b3..79186c2 100755
--- a/src/test/run_test_subnets.pl
+++ b/src/test/run_test_subnets.pl
@@ -237,7 +237,13 @@ foreach my $path (@plugins) {
 	. $ip
 	. '":{"gateway":1},"'
 	. $ipnextfree
-	. '":{},"'
+	. '":{"hostname":"'
+        . $hostname
+        . '","mac":"'
+	. $mac
+	. '","vmid":"'
+	. $vmid
+        . '"},"'
 	. $ip2
 	. '":{"hostname":"'
 	. $hostname
@@ -268,7 +274,13 @@ foreach my $path (@plugins) {
 	. $subnet_cidr
 	. '":{"ips":{"'
 	. $ipnextfree
-	. '":{},"'
+	. '":{"hostname":"'
+        . $hostname
+        . '","mac":"'
+	. $mac
+	. '","vmid":"'
+	. $vmid
+        . '"},"'
 	. $ip2
 	. '":{"hostname":"'
 	. $hostname
@@ -328,7 +340,13 @@ foreach my $path (@plugins) {
 	. $subnet_cidr
 	. '":{"ips":{"'
 	. $ipnextfree
-	. '":{},"'
+	. '":{"hostname":"'
+        . $hostname
+        . '","mac":"'
+	. $mac
+	. '","vmid":"'
+	. $vmid
+        . '"},"'
 	. $ip2
 	. '":{"hostname":"'
 	. $hostname
diff --git a/src/test/run_test_vnets_blackbox.pl b/src/test/run_test_vnets_blackbox.pl
index f7caca2..b79e1dc 100755
--- a/src/test/run_test_vnets_blackbox.pl
+++ b/src/test/run_test_vnets_blackbox.pl
@@ -413,7 +413,6 @@ sub test_nic_join {
     die "$test_name: we're expecting an array of subnets" if !$subnets;
     my $num_subnets = scalar $subnets->@*;
     die "$test_name: we're expecting an array of subnets. $num_subnets elements found" if ($num_subnets < 1);
-    my $num_dhcp_ranges = scalar grep { $_->{'dhcp-range'} } $subnets->@*;
 
     my $zoneid = "TESTZONE";
     my $vnetid = "testvnet";
@@ -452,7 +451,7 @@ sub test_nic_join {
 
     my @ips = get_ips_from_mac($mac);
     my $num_ips = scalar @ips;
-    is ($num_ips, $num_dhcp_ranges, "$test_name: Expecting $num_dhcp_ranges IPs, found $num_ips");
+    is ($num_ips, $num_subnets, "$test_name: Expecting $num_subnets IPs, found $num_ips");
     ok ((all { ($_->{vnet} eq $vnetid && $_->{zone} eq $zoneid) } @ips),
 	"$test_name: all IPs in correct vnet and zone"
     );
@@ -678,8 +677,7 @@ sub test_nic_start {
     die "$test_name: we're expecting an array of subnets" if !$subnets;
     my $num_subnets = scalar $subnets->@*;
     die "$test_name: we're expecting an array of subnets. $num_subnets elements found" if ($num_subnets < 1);
-
-    $num_expected_ips = scalar grep { $_->{'dhcp-range'} } $subnets->@* if !defined $num_expected_ips;
+    $num_expected_ips = $num_subnets if !defined $num_expected_ips;
 
     my $zoneid = "TESTZONE";
     my $vnetid = "testvnet";
-- 
2.39.5



[-- Attachment #2: Type: text/plain, Size: 160 bytes --]

_______________________________________________
pve-devel mailing list
pve-devel@lists.proxmox.com
https://lists.proxmox.com/cgi-bin/mailman/listinfo/pve-devel

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [pve-devel] (no subject)
       [not found] ` <20241209113158.7343-3-lou.lecrivain@wdz.de>
@ 2024-12-12 13:52   ` Stefan Hanreich
  0 siblings, 0 replies; 8+ messages in thread
From: Stefan Hanreich @ 2024-12-12 13:52 UTC (permalink / raw)
  To: Lou Lecrivain, pve-devel

On 12/9/24 12:31, Lou Lecrivain wrote:
> (configure_range is now noop)
> 
> Signed-off-by: lou lecrivain <lou.lecrivain@wdz.de>
> ---
>  src/PVE/Network/SDN/Dhcp.pm         |  3 ++-
>  src/PVE/Network/SDN/Dhcp/Dnsmasq.pm | 23 ++++++++++-------------
>  2 files changed, 12 insertions(+), 14 deletions(-)
> 
> diff --git a/src/PVE/Network/SDN/Dhcp.pm b/src/PVE/Network/SDN/Dhcp.pm
> index d48de34..3ee18e0 100644
> --- a/src/PVE/Network/SDN/Dhcp.pm
> +++ b/src/PVE/Network/SDN/Dhcp.pm
> @@ -98,11 +98,12 @@ sub regenerate_config {
>  		my $subnet_config = $subnets->{$subnet_id};
>  		my $dhcp_ranges = PVE::Network::SDN::Subnets::get_dhcp_ranges($subnet_config);
>  
> +		next if !$dhcp_ranges;
>  		my ($zone, $subnet_network, $subnet_mask) = split(/-/, $subnet_id);
>  		next if $zone ne $zoneid;
> -		next if !$dhcp_ranges;

I think this check could actually be skipped altogether. Since
$dhcp_ranges is a reference it will always be truthy. We only use this
for iterating over @$dhcp_ranges anyway - so if it's empty it is a skip
anyway..

This is pre-existing though and could be massaged in on committing I
suppose, so not necessarily a reason for a v3.

@Thomas: if you want to I can just submit a separate patch for this as
well but this doesn't affect the functionality of this patch series in
any form.


_______________________________________________
pve-devel mailing list
pve-devel@lists.proxmox.com
https://lists.proxmox.com/cgi-bin/mailman/listinfo/pve-devel


^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [pve-devel] SPAM: [PATCH pve-network v2 1/4] vnet: do not skip if no range is defined, ask for allocation inside prefix instead
  2024-12-09 11:31 ` [pve-devel] SPAM: [PATCH pve-network v2 1/4] vnet: do not skip if no range is defined, ask for allocation inside prefix instead Lou Lecrivain via pve-devel
@ 2024-12-12 13:58   ` Stefan Hanreich
  0 siblings, 0 replies; 8+ messages in thread
From: Stefan Hanreich @ 2024-12-12 13:58 UTC (permalink / raw)
  To: Proxmox VE development discussion

Gave this a quick spin on my machine. The remark regarding the check for
dhcp-range could be massaged in or submitted by me in a separate patch,
depending on preference.

Otherwise, consider this:
Tested-by: Stefan Hanreich <s.hanreich@proxmox.com>
Reviewed-by: Stefan Hanreich <s.hanreich@proxmox.com>


_______________________________________________
pve-devel mailing list
pve-devel@lists.proxmox.com
https://lists.proxmox.com/cgi-bin/mailman/listinfo/pve-devel


^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [pve-devel] (no subject)
       [not found] <20240522120553.49114-1-krambrock@hrz.uni-marburg.de>
@ 2024-06-05  8:56 ` Shannon Sterz
  0 siblings, 0 replies; 8+ messages in thread
From: Shannon Sterz @ 2024-06-05  8:56 UTC (permalink / raw)
  To: Daniel Krambrock, pve-devel

On Wed May 22, 2024 at 2:05 PM CEST, Daniel Krambrock wrote:
> This series of patches let the user choose a VMID suggestion strategy
> to avoid the recycled VMID problem.

Hi Daniel!

Thanks for your contribution! First of some top-level feedback:

- Please familiarize yourself with the Developer Documentation [1], Perl
  [2], and JavaScript [3] style guides before contributing.
- Most importantly, if you haven't already, please contact
  `office@proxmox.com` about signing the Harmony CLA [4].
- All your patches provide the same git short message. Please provide
  more specific context for each patch and not just the the overall goal
  of your series.

> Default is 'next-free', the previous strategy where the suggested VMID
> is the lowest not used ID in range. This reuses VMIDs.
> Added options are:
> - 'max-1': selects the highest existing VMID and adds 1

I'm guessing you typo-ed the `max-1` here, as the other patches seem to
correctly use `max+1`. Please note that such a strategy is still prone
to re-use of IDs if one where to remove the VM with the highest ID.

> - 'list': returns the lowest free VMID within the specified
>   range that is not on a list of previously used VMIDs
> On guest deletion the VMID is added to '/etc/pve/used_vmids.list'

Not sure if tracking the used VM/CT IDs in a separate file is the most
elegant solution here. Especially as this is a somewhat niche usecase.

Anyway, I'll provide some more detailed feedback in-line.

Kind regards, Shannon

PS: Please use "reply-all" when replying to me, so the full discussion
stays on the mailing list. Thanks!




_______________________________________________
pve-devel mailing list
pve-devel@lists.proxmox.com
https://lists.proxmox.com/cgi-bin/mailman/listinfo/pve-devel


^ permalink raw reply	[flat|nested] 8+ messages in thread

* [pve-devel] (no subject)
@ 2024-05-22 12:05 Daniel Krambrock via pve-devel
  0 siblings, 0 replies; 8+ messages in thread
From: Daniel Krambrock via pve-devel @ 2024-05-22 12:05 UTC (permalink / raw)
  To: pve-devel; +Cc: Daniel Krambrock

[-- Attachment #1: Type: message/rfc822, Size: 4492 bytes --]

From: Daniel Krambrock <krambrock@hrz.uni-marburg.de>
To: pve-devel@lists.proxmox.com
Subject: 
Date: Wed, 22 May 2024 14:05:49 +0200
Message-ID: <20240522120553.49114-1-krambrock@hrz.uni-marburg.de>

This series of patches let the user choose a VMID suggestion strategy 
to avoid the recycled VMID problem.

Default is 'next-free', the previous strategy where the suggested VMID
is the lowest not used ID in range. This reuses VMIDs.
Added options are:
- 'max-1': selects the highest existing VMID and adds 1
- 'list': returns the lowest free VMID within the specified
  range that is not on a list of previously used VMIDs
On guest deletion the VMID is added to '/etc/pve/used_vmids.list'





[-- Attachment #2: Type: text/plain, Size: 160 bytes --]

_______________________________________________
pve-devel mailing list
pve-devel@lists.proxmox.com
https://lists.proxmox.com/cgi-bin/mailman/listinfo/pve-devel

^ permalink raw reply	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2024-12-12 13:58 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
     [not found] <20241209113158.7343-1-lou.lecrivain@wdz.de>
2024-12-09 11:31 ` [pve-devel] SPAM: [PATCH pve-network v2 1/4] vnet: do not skip if no range is defined, ask for allocation inside prefix instead Lou Lecrivain via pve-devel
2024-12-12 13:58   ` Stefan Hanreich
2024-12-09 11:31 ` [pve-devel] SPAM: [PATCH pve-network v2 2/4] dhcp: always generate dhcp-range for dnsmasq Lou Lecrivain via pve-devel
2024-12-09 11:31 ` [pve-devel] SPAM: [PATCH pve-network v2 3/4] fix: register details in pve ipam db for add_next_freeip Lou Lecrivain via pve-devel
2024-12-09 11:31 ` [pve-devel] SPAM: [PATCH pve-network v2 4/4] update tests following changes to behaviour: - allocating IPs also when prefix-only - PVE IPAM register details for every allocation strategy Lou Lecrivain via pve-devel
     [not found] ` <20241209113158.7343-3-lou.lecrivain@wdz.de>
2024-12-12 13:52   ` [pve-devel] (no subject) Stefan Hanreich
     [not found] <20240522120553.49114-1-krambrock@hrz.uni-marburg.de>
2024-06-05  8:56 ` Shannon Sterz
2024-05-22 12:05 Daniel Krambrock via pve-devel

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
Service provided by Proxmox Server Solutions GmbH | Privacy | Legal