From e97b9f6d3e14757288d7b2f415b69aef222e8e99 Mon Sep 17 00:00:00 2001 From: Noel Georgi Date: Fri, 5 Aug 2022 00:40:07 +0530 Subject: [PATCH] feat: support dhcp options for vlan Add `DHCPOptions` for VLAN device. Fixes: #6011 Signed-off-by: Noel Georgi --- .../controllers/network/operator_config.go | 27 +++++++++++++++++-- .../network/operator_config_test.go | 12 +++++++++ pkg/machinery/config/provider.go | 1 + .../types/v1alpha1/v1alpha1_provider.go | 12 +++++++++ .../config/types/v1alpha1/v1alpha1_types.go | 4 +++ .../types/v1alpha1/v1alpha1_types_doc.go | 11 +++++++- .../types/v1alpha1/zz_generated.deepcopy.go | 5 ++++ .../content/v1.2/reference/configuration.md | 2 ++ 8 files changed, 71 insertions(+), 3 deletions(-) diff --git a/internal/app/machined/pkg/controllers/network/operator_config.go b/internal/app/machined/pkg/controllers/network/operator_config.go index c46f9ef7b..f6acd5f56 100644 --- a/internal/app/machined/pkg/controllers/network/operator_config.go +++ b/internal/app/machined/pkg/controllers/network/operator_config.go @@ -152,13 +152,36 @@ func (ctrl *OperatorConfigController) Run(ctx context.Context, r controller.Runt } for _, vlan := range device.Vlans() { - if vlan.DHCP() { + if vlan.DHCP() && vlan.DHCPOptions().IPv4() { + routeMetric := vlan.DHCPOptions().RouteMetric() + if routeMetric == 0 { + routeMetric = DefaultRouteMetric + } + specs = append(specs, network.OperatorSpecSpec{ Operator: network.OperatorDHCP4, LinkName: fmt.Sprintf("%s.%d", device.Interface(), vlan.ID()), RequireUp: true, DHCP4: network.DHCP4OperatorSpec{ - RouteMetric: DefaultRouteMetric, + RouteMetric: routeMetric, + }, + ConfigLayer: network.ConfigMachineConfiguration, + }) + } + + if vlan.DHCP() && vlan.DHCPOptions().IPv6() { + routeMetric := vlan.DHCPOptions().RouteMetric() + if routeMetric == 0 { + routeMetric = DefaultRouteMetric + } + + specs = append(specs, network.OperatorSpecSpec{ + Operator: network.OperatorDHCP6, + LinkName: fmt.Sprintf("%s.%d", device.Interface(), vlan.ID()), + RequireUp: true, + DHCP6: network.DHCP6OperatorSpec{ + RouteMetric: routeMetric, + DUID: vlan.DHCPOptions().DUIDv6(), }, ConfigLayer: network.ConfigMachineConfiguration, }) diff --git a/internal/app/machined/pkg/controllers/network/operator_config_test.go b/internal/app/machined/pkg/controllers/network/operator_config_test.go index 111005b7b..9cae10595 100644 --- a/internal/app/machined/pkg/controllers/network/operator_config_test.go +++ b/internal/app/machined/pkg/controllers/network/operator_config_test.go @@ -305,6 +305,12 @@ func (suite *OperatorConfigSuite) TestMachineConfigurationDHCP4() { { VlanID: 26, }, + { + VlanID: 27, + VlanDHCPOptions: &v1alpha1.DHCPOptions{ + DHCPRouteMetric: 256, + }, + }, }, }, { @@ -348,6 +354,12 @@ func (suite *OperatorConfigSuite) TestMachineConfigurationDHCP4() { case "configuration/dhcp4/eth4.25": suite.Assert().Equal("eth4.25", r.TypedSpec().LinkName) suite.Assert().EqualValues(netctrl.DefaultRouteMetric, r.TypedSpec().DHCP4.RouteMetric) + case "configuration/dhcp4/eth4.26": + suite.Assert().Equal("eth4.26", r.TypedSpec().LinkName) + suite.Assert().EqualValues(netctrl.DefaultRouteMetric, r.TypedSpec().DHCP4.RouteMetric) + case "configuration/dhcp4/eth4.27": + suite.Assert().Equal("eth4.27", r.TypedSpec().LinkName) + suite.Assert().EqualValues(256, r.TypedSpec().DHCP4.RouteMetric) } return nil diff --git a/pkg/machinery/config/provider.go b/pkg/machinery/config/provider.go index a948e6178..e4cbf7d78 100644 --- a/pkg/machinery/config/provider.go +++ b/pkg/machinery/config/provider.go @@ -268,6 +268,7 @@ type Vlan interface { ID() uint16 MTU() uint32 VIPConfig() VIPConfig + DHCPOptions() DHCPOptions } // Route represents a network route. diff --git a/pkg/machinery/config/types/v1alpha1/v1alpha1_provider.go b/pkg/machinery/config/types/v1alpha1/v1alpha1_provider.go index 7b06c6175..70b83abe4 100644 --- a/pkg/machinery/config/types/v1alpha1/v1alpha1_provider.go +++ b/pkg/machinery/config/types/v1alpha1/v1alpha1_provider.go @@ -977,6 +977,18 @@ func (v *Vlan) DHCP() bool { return pointer.SafeDeref(v.VlanDHCP) } +// DHCPOptions implements the MachineNetwork interface. +func (v *Vlan) DHCPOptions() config.DHCPOptions { + // Default route metric on systemd is 1024. This sets the same. + if v.VlanDHCPOptions == nil { + return &DHCPOptions{ + DHCPRouteMetric: uint32(0), + } + } + + return v.VlanDHCPOptions +} + // ID implements the MachineNetwork interface. func (v *Vlan) ID() uint16 { return v.VlanID diff --git a/pkg/machinery/config/types/v1alpha1/v1alpha1_types.go b/pkg/machinery/config/types/v1alpha1/v1alpha1_types.go index 4d5e85092..bf88c3779 100644 --- a/pkg/machinery/config/types/v1alpha1/v1alpha1_types.go +++ b/pkg/machinery/config/types/v1alpha1/v1alpha1_types.go @@ -2250,6 +2250,10 @@ type Vlan struct { VlanMTU uint32 `yaml:"mtu,omitempty"` // description: The VLAN's virtual IP address configuration. VlanVIP *DeviceVIPConfig `yaml:"vip,omitempty"` + // description: | + // DHCP specific options. + // `dhcp` *must* be set to true for these to take effect. + VlanDHCPOptions *DHCPOptions `yaml:"dhcpOptions,omitempty"` } // Route represents a network route. diff --git a/pkg/machinery/config/types/v1alpha1/v1alpha1_types_doc.go b/pkg/machinery/config/types/v1alpha1/v1alpha1_types_doc.go index 292e8cb82..d2a62eb80 100644 --- a/pkg/machinery/config/types/v1alpha1/v1alpha1_types_doc.go +++ b/pkg/machinery/config/types/v1alpha1/v1alpha1_types_doc.go @@ -1740,6 +1740,10 @@ func init() { TypeName: "Device", FieldName: "dhcpOptions", }, + { + TypeName: "Vlan", + FieldName: "dhcpOptions", + }, } DHCPOptionsDoc.Fields = make([]encoder.Doc, 4) DHCPOptionsDoc.Fields[0].Name = "routeMetric" @@ -2089,7 +2093,7 @@ func init() { FieldName: "vlans", }, } - VlanDoc.Fields = make([]encoder.Doc, 7) + VlanDoc.Fields = make([]encoder.Doc, 8) VlanDoc.Fields[0].Name = "addresses" VlanDoc.Fields[0].Type = "[]string" VlanDoc.Fields[0].Note = "" @@ -2120,6 +2124,11 @@ func init() { VlanDoc.Fields[6].Note = "" VlanDoc.Fields[6].Description = "The VLAN's virtual IP address configuration." VlanDoc.Fields[6].Comments[encoder.LineComment] = "The VLAN's virtual IP address configuration." + VlanDoc.Fields[7].Name = "dhcpOptions" + VlanDoc.Fields[7].Type = "DHCPOptions" + VlanDoc.Fields[7].Note = "" + VlanDoc.Fields[7].Description = "DHCP specific options.\n`dhcp` *must* be set to true for these to take effect." + VlanDoc.Fields[7].Comments[encoder.LineComment] = "DHCP specific options." RouteDoc.Type = "Route" RouteDoc.Comments[encoder.LineComment] = "Route represents a network route." diff --git a/pkg/machinery/config/types/v1alpha1/zz_generated.deepcopy.go b/pkg/machinery/config/types/v1alpha1/zz_generated.deepcopy.go index 5c525819d..e1aca5a82 100644 --- a/pkg/machinery/config/types/v1alpha1/zz_generated.deepcopy.go +++ b/pkg/machinery/config/types/v1alpha1/zz_generated.deepcopy.go @@ -2084,6 +2084,11 @@ func (in *Vlan) DeepCopyInto(out *Vlan) { *out = new(DeviceVIPConfig) (*in).DeepCopyInto(*out) } + if in.VlanDHCPOptions != nil { + in, out := &in.VlanDHCPOptions, &out.VlanDHCPOptions + *out = new(DHCPOptions) + (*in).DeepCopyInto(*out) + } return } diff --git a/website/content/v1.2/reference/configuration.md b/website/content/v1.2/reference/configuration.md index a2e7fdd48..aa7e3ba57 100644 --- a/website/content/v1.2/reference/configuration.md +++ b/website/content/v1.2/reference/configuration.md @@ -2087,6 +2087,7 @@ DHCPOptions contains options for configuring the DHCP settings for a given inter Appears in: - Device.dhcpOptions +- Vlan.dhcpOptions @@ -2342,6 +2343,7 @@ Appears in: |`vlanId` |uint16 |The VLAN's ID. | | |`mtu` |uint32 |The VLAN's MTU. | | |`vip` |DeviceVIPConfig |The VLAN's virtual IP address configuration. | | +|`dhcpOptions` |DHCPOptions |
DHCP specific options.`dhcp` *must* be set to true for these to take effect.
| |