Skip to content

Commit

Permalink
feat: bring unconfigured links with link carrier up by default
Browse files Browse the repository at this point in the history
This matches previous networkd implementation to make sure we can run
DHCP on the interfaces which are not explicitly brought up.

Signed-off-by: Andrey Smirnov <smirnov.andrey@gmail.com>
  • Loading branch information
smira authored and talos-bot committed Jun 9, 2021
1 parent 02bd657 commit f93c9c8
Show file tree
Hide file tree
Showing 2 changed files with 154 additions and 8 deletions.
69 changes: 61 additions & 8 deletions internal/app/machined/pkg/controllers/network/link_config.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,11 @@ func (ctrl *LinkConfigController) Inputs() []controller.Input {
ID: pointer.ToString(config.V1Alpha1ID),
Kind: controller.InputWeak,
},
{
Namespace: network.NamespaceName,
Type: network.LinkStatusType,
Kind: controller.InputWeak,
},
}
}

Expand Down Expand Up @@ -111,7 +116,7 @@ func (ctrl *LinkConfigController) Run(ctx context.Context, r controller.Runtime,
}

// parse kernel cmdline for the interface name
cmdlineLink := ctrl.parseCmdline(logger)
cmdlineLink, cmdlineIgnored := ctrl.parseCmdline(logger)
if cmdlineLink.Name != "" {
if _, ignored := ignoredInterfaces[cmdlineLink.Name]; !ignored {
var ids []string
Expand All @@ -127,7 +132,7 @@ func (ctrl *LinkConfigController) Run(ctx context.Context, r controller.Runtime,
}
}

// parse machine configuration for static routes
// parse machine configuration for link specs
if cfgProvider != nil {
links := ctrl.parseMachineConfiguration(logger, cfgProvider)

Expand All @@ -143,8 +148,56 @@ func (ctrl *LinkConfigController) Run(ctx context.Context, r controller.Runtime,
}
}

// list link for cleanup
list, err := r.List(ctx, resource.NewMetadata(network.ConfigNamespaceName, network.LinkSpecType, "", resource.VersionUndefined))
// bring up any physical link not mentioned explicitly in the machine configuration
configuredLinks := map[string]struct{}{}

for _, linkName := range cmdlineIgnored {
configuredLinks[linkName] = struct{}{}
}

if cmdlineLink.Name != "" {
configuredLinks[cmdlineLink.Name] = struct{}{}
}

if cfgProvider != nil {
for _, device := range cfgProvider.Machine().Network().Devices() {
configuredLinks[device.Interface()] = struct{}{}
}
}

list, err := r.List(ctx, resource.NewMetadata(network.NamespaceName, network.LinkStatusType, "", resource.VersionUndefined))
if err != nil {
return fmt.Errorf("error listing link statuses: %w", err)
}

for _, item := range list.Items {
linkStatus := item.(*network.LinkStatus) //nolint:errcheck,forcetypeassert

if _, configured := configuredLinks[linkStatus.Metadata().ID()]; !configured {
if linkStatus.Physical() {
var ids []string

ids, err = ctrl.apply(ctx, r, []network.LinkSpecSpec{
{
Name: linkStatus.Metadata().ID(),
Up: true,
ConfigLayer: network.ConfigDefault,
},
})

if err != nil {
return fmt.Errorf("error applying default link up: %w", err)
}

for _, id := range ids {
touchedIDs[id] = struct{}{}
}
}
}
}

// list links for cleanup
list, err = r.List(ctx, resource.NewMetadata(network.ConfigNamespaceName, network.LinkSpecType, "", resource.VersionUndefined))
if err != nil {
return fmt.Errorf("error listing resources: %w", err)
}
Expand Down Expand Up @@ -189,23 +242,23 @@ func (ctrl *LinkConfigController) apply(ctx context.Context, r controller.Runtim
return ids, nil
}

func (ctrl *LinkConfigController) parseCmdline(logger *zap.Logger) network.LinkSpecSpec {
func (ctrl *LinkConfigController) parseCmdline(logger *zap.Logger) (network.LinkSpecSpec, []string) {
if ctrl.Cmdline == nil {
return network.LinkSpecSpec{}
return network.LinkSpecSpec{}, nil
}

settings, err := ParseCmdlineNetwork(ctrl.Cmdline)
if err != nil {
logger.Info("ignoring error", zap.Error(err))

return network.LinkSpecSpec{}
return network.LinkSpecSpec{}, nil
}

return network.LinkSpecSpec{
Name: settings.LinkName,
Up: true,
ConfigLayer: network.ConfigCmdline,
}
}, settings.IgnoreInterfaces
}

//nolint:gocyclo
Expand Down
93 changes: 93 additions & 0 deletions internal/app/machined/pkg/controllers/network/link_config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,28 @@ func (suite *LinkConfigSuite) assertLinks(requiredIDs []string, check func(*netw
return nil
}

func (suite *LinkConfigSuite) assertNoLinks(unexpectedIDs []string) error {
unexpIDs := make(map[string]struct{}, len(unexpectedIDs))

for _, id := range unexpectedIDs {
unexpIDs[id] = struct{}{}
}

resources, err := suite.state.List(suite.ctx, resource.NewMetadata(network.ConfigNamespaceName, network.LinkSpecType, "", resource.VersionUndefined))
if err != nil {
return err
}

for _, res := range resources.Items {
_, unexpected := unexpIDs[res.Metadata().ID()]
if unexpected {
return retry.ExpectedErrorf("unexpected ID %q", res.Metadata().ID())
}
}

return nil
}

func (suite *LinkConfigSuite) TestLoopback() {
suite.Require().NoError(suite.runtime.RegisterController(&netctrl.LinkConfigController{}))

Expand Down Expand Up @@ -289,6 +311,77 @@ func (suite *LinkConfigSuite) TestMachineConfiguration() {
}))
}

func (suite *LinkConfigSuite) TestDefaultUp() {
suite.Require().NoError(suite.runtime.RegisterController(&netctrl.LinkConfigController{
Cmdline: procfs.NewCmdline("talos.network.interface.ignore=eth2"),
}))

for _, link := range []string{"eth0", "eth1", "eth2"} {
linkStatus := network.NewLinkStatus(network.NamespaceName, link)
linkStatus.TypedSpec().Type = nethelpers.LinkEther
linkStatus.TypedSpec().LinkState = true

suite.Require().NoError(suite.state.Create(suite.ctx, linkStatus))
}

u, err := url.Parse("https://foo:6443")
suite.Require().NoError(err)

cfg := config.NewMachineConfig(&v1alpha1.Config{
ConfigVersion: "v1alpha1",
MachineConfig: &v1alpha1.MachineConfig{
MachineNetwork: &v1alpha1.NetworkConfig{
NetworkInterfaces: []*v1alpha1.Device{
{
DeviceInterface: "eth0",
DeviceVlans: []*v1alpha1.Vlan{
{
VlanID: 24,
VlanCIDR: "10.0.0.1/8",
},
{
VlanID: 48,
VlanCIDR: "10.0.0.2/8",
},
},
},
},
},
},
ClusterConfig: &v1alpha1.ClusterConfig{
ControlPlane: &v1alpha1.ControlPlaneConfig{
Endpoint: &v1alpha1.Endpoint{
URL: u,
},
},
},
})

suite.Require().NoError(suite.state.Create(suite.ctx, cfg))

suite.startRuntime()

suite.Assert().NoError(retry.Constant(3*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
func() error {
return suite.assertLinks([]string{
"default/eth1",
}, func(r *network.LinkSpec) error {
suite.Assert().Equal(network.ConfigDefault, r.TypedSpec().ConfigLayer)
suite.Assert().True(r.TypedSpec().Up)

return nil
})
}))

suite.Assert().NoError(retry.Constant(3*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
func() error {
return suite.assertNoLinks([]string{
"default/eth0",
"default/eth2",
})
}))
}

func TestLinkConfigSuite(t *testing.T) {
suite.Run(t, new(LinkConfigSuite))
}

0 comments on commit f93c9c8

Please sign in to comment.