Skip to content

Commit 5484579

Browse files
committed
feat: allow link scope routes in the machine config
They were supported internally, but never properly exposed in the machine configuration. Signed-off-by: Andrey Smirnov <andrey.smirnov@talos-systems.com>
1 parent 56b83b0 commit 5484579

File tree

7 files changed

+64
-34
lines changed

7 files changed

+64
-34
lines changed

internal/app/machined/pkg/controllers/network/route_config.go

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -204,7 +204,7 @@ func (ctrl *RouteConfigController) parseCmdline(logger *zap.Logger) (route netwo
204204
return route
205205
}
206206

207-
//nolint:gocyclo
207+
//nolint:gocyclo,cyclop
208208
func (ctrl *RouteConfigController) parseMachineConfiguration(logger *zap.Logger, cfgProvider talosconfig.Provider) (routes []network.RouteSpecSpec) {
209209
convert := func(linkName string, in talosconfig.Route) (route network.RouteSpecSpec, err error) {
210210
if in.Network() != "" {
@@ -214,9 +214,11 @@ func (ctrl *RouteConfigController) parseMachineConfiguration(logger *zap.Logger,
214214
}
215215
}
216216

217-
route.Gateway, err = netaddr.ParseIP(in.Gateway())
218-
if err != nil {
219-
return route, fmt.Errorf("error parsing route gateway: %w", err)
217+
if in.Gateway() != "" {
218+
route.Gateway, err = netaddr.ParseIP(in.Gateway())
219+
if err != nil {
220+
return route, fmt.Errorf("error parsing route gateway: %w", err)
221+
}
220222
}
221223

222224
if in.Source() != "" {
@@ -233,9 +235,12 @@ func (ctrl *RouteConfigController) parseMachineConfiguration(logger *zap.Logger,
233235
route.Priority = DefaultRouteMetric
234236
}
235237

236-
if route.Gateway.Is6() {
238+
switch {
239+
case !route.Gateway.IsZero() && route.Gateway.Is6():
237240
route.Family = nethelpers.FamilyInet6
238-
} else {
241+
case !route.Destination.IsZero() && route.Destination.IP().Is6():
242+
route.Family = nethelpers.FamilyInet6
243+
default:
239244
route.Family = nethelpers.FamilyInet4
240245
}
241246

internal/app/machined/pkg/controllers/network/route_config_test.go

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -141,6 +141,9 @@ func (suite *RouteConfigSuite) TestMachineConfiguration() {
141141
RouteGateway: "192.168.0.25",
142142
RouteMetric: 25,
143143
},
144+
{
145+
RouteNetwork: "169.254.254.254/32",
146+
},
144147
},
145148
},
146149
{
@@ -212,6 +215,7 @@ func (suite *RouteConfigSuite) TestMachineConfiguration() {
212215
"configuration/inet4/10.0.3.1/10.0.3.0/24/1024",
213216
"configuration/inet4/192.168.0.25/192.168.0.0/18/25",
214217
"configuration/inet4/192.244.0.1/192.244.0.0/24/1024",
218+
"configuration/inet4//169.254.254.254/32/1024",
215219
}, func(r *network.RouteSpec) error {
216220
switch r.Metadata().ID() {
217221
case "configuration/inet6/2001:470:6d:30e:8ed2:b60c:9d2f:803b//1024":
@@ -231,6 +235,12 @@ func (suite *RouteConfigSuite) TestMachineConfiguration() {
231235
suite.Assert().Equal(nethelpers.FamilyInet4, r.TypedSpec().Family)
232236
suite.Assert().EqualValues(netctrl.DefaultRouteMetric, r.TypedSpec().Priority)
233237
suite.Assert().EqualValues(netaddr.MustParseIP("192.244.0.10"), r.TypedSpec().Source)
238+
case "configuration/inet4//169.254.254.254/32/1024":
239+
suite.Assert().Equal("eth3", r.TypedSpec().OutLinkName)
240+
suite.Assert().Equal(nethelpers.FamilyInet4, r.TypedSpec().Family)
241+
suite.Assert().EqualValues(netctrl.DefaultRouteMetric, r.TypedSpec().Priority)
242+
suite.Assert().Equal(nethelpers.ScopeLink, r.TypedSpec().Scope)
243+
suite.Assert().Equal("169.254.254.254/32", r.TypedSpec().Destination.String())
234244
}
235245

236246
suite.Assert().Equal(network.ConfigMachineConfiguration, r.TypedSpec().ConfigLayer)

pkg/machinery/config/types/v1alpha1/v1alpha1_types.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1927,9 +1927,9 @@ type Vlan struct {
19271927

19281928
// Route represents a network route.
19291929
type Route struct {
1930-
// description: The route's network.
1930+
// description: The route's network (destination).
19311931
RouteNetwork string `yaml:"network"`
1932-
// description: The route's gateway.
1932+
// description: The route's gateway (if empty, creates link scope route).
19331933
RouteGateway string `yaml:"gateway"`
19341934
// description: The route's source address (optional).
19351935
RouteSource string `yaml:"source,omitempty"`

pkg/machinery/config/types/v1alpha1/v1alpha1_types_doc.go

Lines changed: 4 additions & 4 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

pkg/machinery/config/types/v1alpha1/v1alpha1_validation.go

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -681,6 +681,8 @@ func CheckDeviceAddressing(d *Device, bondedInterfaces map[string]string) ([]str
681681
}
682682

683683
// CheckDeviceRoutes ensures that the specified routes are valid.
684+
//
685+
//nolint:gocyclo
684686
func CheckDeviceRoutes(d *Device, bondedInterfaces map[string]string) ([]string, error) {
685687
var result *multierror.Error
686688

@@ -699,8 +701,14 @@ func CheckDeviceRoutes(d *Device, bondedInterfaces map[string]string) ([]string,
699701
}
700702
}
701703

702-
if ip := net.ParseIP(route.Gateway()); ip == nil {
703-
result = multierror.Append(result, fmt.Errorf("[%s] %q: %w", "networking.os.device.route["+strconv.Itoa(idx)+"].gateway", route.Gateway(), ErrInvalidAddress))
704+
if route.Gateway() != "" {
705+
if ip := net.ParseIP(route.Gateway()); ip == nil {
706+
result = multierror.Append(result, fmt.Errorf("[%s] %q: %w", "networking.os.device.route["+strconv.Itoa(idx)+"].gateway", route.Gateway(), ErrInvalidAddress))
707+
}
708+
}
709+
710+
if route.Gateway() == "" && route.Network() == "" {
711+
result = multierror.Append(result, fmt.Errorf("[%s]: %s", "networking.os.device.route["+strconv.Itoa(idx)+"]", "either network or gateway should be set"))
704712
}
705713

706714
if route.Source() != "" {

pkg/machinery/config/types/v1alpha1/v1alpha1_validation_test.go

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -737,6 +737,12 @@ func TestValidate(t *testing.T) {
737737
RouteGateway: "10.0.0.1",
738738
RouteSource: "10.0.0.3/32",
739739
},
740+
{
741+
RouteNetwork: "169.254.254.254/32",
742+
},
743+
{
744+
RouteSource: "10.0.0.3",
745+
},
740746
},
741747
},
742748
},
@@ -750,9 +756,10 @@ func TestValidate(t *testing.T) {
750756
},
751757
},
752758
},
753-
expectedError: "3 errors occurred:\n\t* [networking.os.device.route[3].gateway] \"172.0.0.x\": invalid network address\n" +
759+
expectedError: "4 errors occurred:\n\t* [networking.os.device.route[3].gateway] \"172.0.0.x\": invalid network address\n" +
754760
"\t* [networking.os.device.route[4].network] \"10.0.0.0\": invalid network address\n" +
755-
"\t* [networking.os.device.route[5].source] \"10.0.0.3/32\": invalid network address\n\n",
761+
"\t* [networking.os.device.route[5].source] \"10.0.0.3/32\": invalid network address\n" +
762+
"\t* [networking.os.device.route[7]]: either network or gateway should be set\n\n",
756763
},
757764
{
758765
name: "KubeSpanNoDiscovery",

website/content/docs/v0.15/Reference/configuration.md

Lines changed: 18 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -374,8 +374,8 @@ network:
374374
- 192.168.2.0/24
375375
# A list of routes associated with the interface.
376376
routes:
377-
- network: 0.0.0.0/0 # The route's network.
378-
gateway: 192.168.2.1 # The route's gateway.
377+
- network: 0.0.0.0/0 # The route's network (destination).
378+
gateway: 192.168.2.1 # The route's gateway (if empty, creates link scope route).
379379
metric: 1024 # The optional metric for the route.
380380
mtu: 1500 # The interface's MTU.
381381

@@ -1813,8 +1813,8 @@ interfaces:
18131813
- 192.168.2.0/24
18141814
# A list of routes associated with the interface.
18151815
routes:
1816-
- network: 0.0.0.0/0 # The route's network.
1817-
gateway: 192.168.2.1 # The route's gateway.
1816+
- network: 0.0.0.0/0 # The route's network (destination).
1817+
gateway: 192.168.2.1 # The route's gateway (if empty, creates link scope route).
18181818
metric: 1024 # The optional metric for the route.
18191819
mtu: 1500 # The interface's MTU.
18201820

@@ -1918,8 +1918,8 @@ interfaces:
19181918
- 192.168.2.0/24
19191919
# A list of routes associated with the interface.
19201920
routes:
1921-
- network: 0.0.0.0/0 # The route's network.
1922-
gateway: 192.168.2.1 # The route's gateway.
1921+
- network: 0.0.0.0/0 # The route's network (destination).
1922+
gateway: 192.168.2.1 # The route's gateway (if empty, creates link scope route).
19231923
metric: 1024 # The optional metric for the route.
19241924
mtu: 1500 # The interface's MTU.
19251925

@@ -3977,8 +3977,8 @@ Appears in:
39773977
- 192.168.2.0/24
39783978
# A list of routes associated with the interface.
39793979
routes:
3980-
- network: 0.0.0.0/0 # The route's network.
3981-
gateway: 192.168.2.1 # The route's gateway.
3980+
- network: 0.0.0.0/0 # The route's network (destination).
3981+
gateway: 192.168.2.1 # The route's gateway (if empty, creates link scope route).
39823982
metric: 1024 # The optional metric for the route.
39833983
mtu: 1500 # The interface's MTU.
39843984

@@ -4094,10 +4094,10 @@ Examples:
40944094
40954095
``` yaml
40964096
routes:
4097-
- network: 0.0.0.0/0 # The route's network.
4098-
gateway: 10.5.0.1 # The route's gateway.
4099-
- network: 10.2.0.0/16 # The route's network.
4100-
gateway: 10.2.0.1 # The route's gateway.
4097+
- network: 0.0.0.0/0 # The route's network (destination).
4098+
gateway: 10.5.0.1 # The route's gateway (if empty, creates link scope route).
4099+
- network: 10.2.0.0/16 # The route's network (destination).
4100+
gateway: 10.2.0.1 # The route's gateway (if empty, creates link scope route).
41014101
```
41024102
41034103
@@ -5083,10 +5083,10 @@ Appears in:
50835083

50845084

50855085
``` yaml
5086-
- network: 0.0.0.0/0 # The route's network.
5087-
gateway: 10.5.0.1 # The route's gateway.
5088-
- network: 10.2.0.0/16 # The route's network.
5089-
gateway: 10.2.0.1 # The route's gateway.
5086+
- network: 0.0.0.0/0 # The route's network (destination).
5087+
gateway: 10.5.0.1 # The route's gateway (if empty, creates link scope route).
5088+
- network: 10.2.0.0/16 # The route's network (destination).
5089+
gateway: 10.2.0.1 # The route's gateway (if empty, creates link scope route).
50905090
```
50915091

50925092
<hr />
@@ -5098,7 +5098,7 @@ Appears in:
50985098
</div>
50995099
<div class="dt">
51005100

5101-
The route's network.
5101+
The route's network (destination).
51025102

51035103
</div>
51045104

@@ -5110,7 +5110,7 @@ The route's network.
51105110
</div>
51115111
<div class="dt">
51125112

5113-
The route's gateway.
5113+
The route's gateway (if empty, creates link scope route).
51145114

51155115
</div>
51165116

0 commit comments

Comments
 (0)