feat: support MTU and route changes for DHCP
This PR updates the behavior of our machine configs with respect to DHCP-enabled interfaces. Now, if MTU is specified by the user, that value will take precedence over any setting provided by the DHCP server. Additionally, any routes specified will be appended to routes specified by the DHCP server. Signed-off-by: Spencer Smith <robertspencersmith@gmail.com>
This commit is contained in:
@ -1288,6 +1288,8 @@ Type: `string`
|
||||
#### routes
|
||||
|
||||
A list of routes associated with the interface.
|
||||
If used in combination with DHCP, these routes will be appended to routes returned by DHCP server.
|
||||
|
||||
Type: `array`
|
||||
|
||||
#### bond
|
||||
@ -1303,6 +1305,8 @@ Type: `array`
|
||||
#### mtu
|
||||
|
||||
The interface's MTU.
|
||||
If used in combination with DHCP, this will override any MTU settings returned from DHCP server.
|
||||
|
||||
Type: `int`
|
||||
|
||||
#### dhcp
|
||||
|
@ -27,6 +27,8 @@ type DHCP struct {
|
||||
Ack *dhcpv4.DHCPv4
|
||||
NetIf *net.Interface
|
||||
DHCPOptions config.DHCPOptions
|
||||
Mtu int
|
||||
RouteList []config.Route
|
||||
}
|
||||
|
||||
// Name returns back the name of the address method.
|
||||
@ -65,13 +67,20 @@ func (d *DHCP) Mask() net.IPMask {
|
||||
|
||||
// MTU returs the MTU size from the DHCP offer.
|
||||
func (d *DHCP) MTU() uint32 {
|
||||
mtuReturn := uint32(d.NetIf.MTU)
|
||||
|
||||
// TODO do we need to implement dhcpv4.GetUint32 upstream?
|
||||
mtu, err := dhcpv4.GetUint16(dhcpv4.OptionInterfaceMTU, d.Ack.Options)
|
||||
if err != nil {
|
||||
return uint32(d.NetIf.MTU)
|
||||
if err == nil {
|
||||
mtuReturn = uint32(mtu)
|
||||
}
|
||||
|
||||
return uint32(mtu)
|
||||
// override with any non-zero Mtu value passed into the dhcp object
|
||||
if uint32(d.Mtu) > 0 {
|
||||
mtuReturn = uint32(d.Mtu)
|
||||
}
|
||||
|
||||
return mtuReturn
|
||||
}
|
||||
|
||||
// TTL denotes how long a DHCP offer is valid for.
|
||||
@ -108,10 +117,6 @@ func (d *DHCP) Valid() bool {
|
||||
// If the DHCP server returns both a Classless Static Routes option and
|
||||
// a Router option, the DHCP client MUST ignore the Router option.
|
||||
func (d *DHCP) Routes() (routes []*Route) {
|
||||
if len(d.Ack.ClasslessStaticRoute()) > 0 {
|
||||
return d.Ack.ClasslessStaticRoute()
|
||||
}
|
||||
|
||||
defRoute := &net.IPNet{
|
||||
IP: net.IPv4zero,
|
||||
Mask: net.IPv4Mask(0, 0, 0, 0),
|
||||
@ -121,6 +126,19 @@ func (d *DHCP) Routes() (routes []*Route) {
|
||||
routes = append(routes, &Route{Router: router, Dest: defRoute})
|
||||
}
|
||||
|
||||
// overwrite router option if classless routes were provided.
|
||||
if len(d.Ack.ClasslessStaticRoute()) > 0 {
|
||||
routes = d.Ack.ClasslessStaticRoute()
|
||||
}
|
||||
|
||||
// append any routes that were provided in config
|
||||
for _, route := range d.RouteList {
|
||||
// nolint: errcheck
|
||||
_, ipnet, _ := net.ParseCIDR(route.Network())
|
||||
|
||||
routes = append(routes, &Route{Dest: ipnet, Router: net.ParseIP(route.Gateway())})
|
||||
}
|
||||
|
||||
return routes
|
||||
}
|
||||
|
||||
|
@ -46,7 +46,7 @@ func buildOptions(device config.Device, hostname string) (name string, opts []ni
|
||||
|
||||
opts = append(opts, nic.WithAddressing(s))
|
||||
case device.DHCP():
|
||||
d := &address.DHCP{DHCPOptions: device.DHCPOptions()}
|
||||
d := &address.DHCP{DHCPOptions: device.DHCPOptions(), RouteList: device.Routes(), Mtu: device.MTU()}
|
||||
opts = append(opts, nic.WithAddressing(d))
|
||||
default:
|
||||
// Allow master interface without any addressing if VLANs exist
|
||||
|
@ -818,13 +818,17 @@ type Device struct {
|
||||
DeviceInterface string `yaml:"interface"`
|
||||
// description: The CIDR to use.
|
||||
DeviceCIDR string `yaml:"cidr"`
|
||||
// description: A list of routes associated with the interface.
|
||||
// description: |
|
||||
// A list of routes associated with the interface.
|
||||
// If used in combination with DHCP, these routes will be appended to routes returned by DHCP server.
|
||||
DeviceRoutes []*Route `yaml:"routes"`
|
||||
// description: Bond specific options.
|
||||
DeviceBond *Bond `yaml:"bond"`
|
||||
// description: VLAN specific options.
|
||||
DeviceVlans []*Vlan `yaml:"vlans"`
|
||||
// description: The interface's MTU.
|
||||
// description: |
|
||||
// The interface's MTU.
|
||||
// If used in combination with DHCP, this will override any MTU settings returned from DHCP server.
|
||||
DeviceMTU int `yaml:"mtu"`
|
||||
// description: Indicates if DHCP should be used.
|
||||
DeviceDHCP bool `yaml:"dhcp"`
|
||||
|
Reference in New Issue
Block a user