feat: allow ability to create dummy nics

This PR will introduce a new field to v1alpha1 configs that allows users
to set `dummy: true` when specifying interfaces. If present, we will
create a dummy interface with the CIDR information given. This is useful
for users that don't want to use loopback for things like ECMP (or want
more than one dummy interface).

The created dummy interface looked like this with `ip a`:

```
3: dummy0: <BROADCAST,NOARP,UP,LOWER_UP> mtu 1500 qdisc noqueue state UNKNOWN qlen 1000
    link/ether 66:4a:e3:5f:38:10 brd ff:ff:ff:ff:ff:ff
    inet 10.254.0.5/32 brd 10.254.0.5 scope global dummy0
       valid_lft forever preferred_lft forever
```

Will close #2186.

Signed-off-by: Spencer Smith <robertspencersmith@gmail.com>
This commit is contained in:
Spencer Smith 2020-06-16 15:53:13 -04:00 committed by Spencer Smith
parent 718fd28264
commit d57c97fdb6
6 changed files with 29 additions and 0 deletions

View File

@ -737,6 +737,11 @@ The following DHCP options are supported:
`ignore` is used to exclude a specific interface from configuration. `ignore` is used to exclude a specific interface from configuration.
This parameter is optional. This parameter is optional.
##### machine.network.interfaces.dummy
`dummy` is used to specify that this interface should be a virtual-only, dummy interface.
This parameter is optional.
##### machine.network.interfaces.routes ##### machine.network.interfaces.routes
`routes` is used to specify static routes that may be necessary. `routes` is used to specify static routes that may be necessary.

View File

@ -152,6 +152,7 @@ type Device struct {
MTU int `yaml:"mtu"` MTU int `yaml:"mtu"`
DHCP bool `yaml:"dhcp"` DHCP bool `yaml:"dhcp"`
Ignore bool `yaml:"ignore"` Ignore bool `yaml:"ignore"`
Dummy bool `yaml:"dummy"`
} }
// Bond contains the various options for configuring a // Bond contains the various options for configuring a

View File

@ -71,6 +71,11 @@ func buildOptions(device runtime.Device, hostname string) (name string, opts []n
} }
} }
// Handle dummy interface
if device.Dummy {
opts = append(opts, nic.WithDummy())
}
// Configure Bonding // Configure Bonding
if device.Bond == nil { if device.Bond == nil {
return device.Interface, opts, err return device.Interface, opts, err

View File

@ -45,6 +45,7 @@ type NetworkInterface struct {
Name string Name string
Type int Type int
Ignore bool Ignore bool
Dummy bool
Bonded bool Bonded bool
MTU uint32 MTU uint32
Link *net.Interface Link *net.Interface
@ -124,6 +125,10 @@ func (n *NetworkInterface) Create() error {
info = &rtnetlink.LinkInfo{Kind: "bond"} info = &rtnetlink.LinkInfo{Kind: "bond"}
} }
if n.Dummy {
info = &rtnetlink.LinkInfo{Kind: "dummy"}
}
if err = n.createLink(n.Name, info); err != nil { if err = n.createLink(n.Name, info); err != nil {
return err return err
} }

View File

@ -23,6 +23,14 @@ func defaultOptions() *NetworkInterface {
} }
} }
// WithDummy indicates that the interface should be a virtual, dummy interface.
func WithDummy() Option {
return func(n *NetworkInterface) (err error) {
n.Dummy = true
return
}
}
// WithIgnore indicates that the interface should not be processed by talos. // WithIgnore indicates that the interface should not be processed by talos.
func WithIgnore() Option { func WithIgnore() Option {
return func(n *NetworkInterface) (err error) { return func(n *NetworkInterface) (err error) {

View File

@ -436,6 +436,11 @@ type NetworkConfig struct {
// `ignore` is used to exclude a specific interface from configuration. // `ignore` is used to exclude a specific interface from configuration.
// This parameter is optional. // This parameter is optional.
// //
// ##### machine.network.interfaces.dummy
//
// `dummy` is used to specify that this interface should be a virtual-only, dummy interface.
// This parameter is optional.
//
// ##### machine.network.interfaces.routes // ##### machine.network.interfaces.routes
// //
// `routes` is used to specify static routes that may be necessary. // `routes` is used to specify static routes that may be necessary.