Skip to content

Commit a7eb5d2

Browse files
committed
interface dhcp configuration
dhcp should be an opt-in option because running it can cause delays on pod startup on environments that don't have dhcp enabled. Change-Id: I2905788c261583d86a5701576c2e61a245138c02
1 parent 3520dd5 commit a7eb5d2

File tree

5 files changed

+45
-20
lines changed

5 files changed

+45
-20
lines changed

pkg/apis/types.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,10 @@ type InterfaceConfig struct {
4141
// to be assigned to the interface.
4242
Addresses []string `json:"addresses,omitempty"`
4343

44+
// DHCP, if true, indicates that the interface should be configured via DHCP.
45+
// This is mutually exclusive with the 'addresses' field.
46+
DHCP *bool `json:"dhcp,omitempty"`
47+
4448
// MTU is the Maximum Transmission Unit for the interface.
4549
MTU *int32 `json:"mtu,omitempty"`
4650

pkg/apis/validation.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,10 @@ func validateInterfaceConfig(cfg *InterfaceConfig, fieldPath string) (allErrors
128128
}
129129
}
130130

131+
if cfg.DHCP != nil && *cfg.DHCP && len(cfg.Addresses) > 0 {
132+
allErrors = append(allErrors, fmt.Errorf("%s: dhcp and addresses are mutually exclusive", fieldPath))
133+
}
134+
131135
if cfg.MTU != nil {
132136
if *cfg.MTU < MinMTU {
133137
allErrors = append(allErrors, fmt.Errorf("%s.mtu: must be at least %d, got %d", fieldPath, MinMTU, *cfg.MTU))

pkg/apis/validation_test.go

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -253,6 +253,25 @@ func TestValidateInterfaceConfig(t *testing.T) {
253253
expectErr: true,
254254
errCount: 1,
255255
},
256+
{
257+
name: "valid with dhcp",
258+
cfg: &InterfaceConfig{Name: "eth0", DHCP: ptr.To(true)},
259+
fieldPath: "iface",
260+
expectErr: false,
261+
},
262+
{
263+
name: "invalid with dhcp and addresses",
264+
cfg: &InterfaceConfig{Name: "eth0", DHCP: ptr.To(true), Addresses: []string{"10.0.0.1/24"}},
265+
fieldPath: "iface",
266+
expectErr: true,
267+
errCount: 1,
268+
},
269+
{
270+
name: "valid with dhcp false and addresses",
271+
cfg: &InterfaceConfig{Name: "eth0", DHCP: ptr.To(false), Addresses: []string{"10.0.0.1/24"}},
272+
fieldPath: "iface",
273+
expectErr: false,
274+
},
256275
{
257276
name: "multiple errors",
258277
cfg: &InterfaceConfig{Name: "eth/0", Addresses: []string{"badip"}, MTU: ptr.To[int32](0)},

pkg/driver/dhcp.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ import (
2727
"github.com/vishvananda/netlink"
2828
)
2929

30-
func getDHCP(ifName string) (ip string, routes []apis.RouteConfig, err error) {
30+
func getDHCP(ctx context.Context, ifName string) (ip string, routes []apis.RouteConfig, err error) {
3131
link, err := netlink.LinkByName(ifName)
3232
if err != nil {
3333
return "", nil, err
@@ -43,7 +43,7 @@ func getDHCP(ifName string) (ip string, routes []apis.RouteConfig, err error) {
4343
}
4444
defer dhclient.Close()
4545

46-
lease, err := dhclient.Request(context.Background())
46+
lease, err := dhclient.Request(ctx)
4747
if err != nil {
4848
return "", nil, fmt.Errorf("fail to obtain DHCP lease on interface %s up: %v", ifName, err)
4949
}

pkg/driver/dra_hooks.go

Lines changed: 16 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -166,12 +166,25 @@ func (np *NetworkDriver) prepareResourceClaim(ctx context.Context, claim *resour
166166
podCfg.Network.Interface.Name = ifName
167167
}
168168

169-
// If there is no custom addresses then use the existing ones
170-
if len(podCfg.Network.Interface.Addresses) == 0 {
169+
// If DHCP is requested, do a DHCP request to gather the network parameters (IPs and Routes)
170+
// ... but we DO NOT apply them in the root namespace
171+
if podCfg.Network.Interface.DHCP != nil && *podCfg.Network.Interface.DHCP {
172+
klog.V(2).Infof("trying to get network configuration via DHCP")
173+
contextCancel, cancel := context.WithTimeout(ctx, 5*time.Second)
174+
defer cancel()
175+
ip, routes, err := getDHCP(contextCancel, ifName)
176+
if err != nil {
177+
errorList = append(errorList, fmt.Errorf("fail to get configuration via DHCP for %s: %w", ifName, err))
178+
} else {
179+
podCfg.Network.Interface.Addresses = []string{ip}
180+
podCfg.Network.Routes = append(podCfg.Network.Routes, routes...)
181+
}
182+
} else if len(podCfg.Network.Interface.Addresses) == 0 {
183+
// If there is no custom addresses and no DHCP, then use the existing ones
171184
// get the existing IP addresses
172185
nlAddresses, err := nlHandle.AddrList(link, netlink.FAMILY_ALL)
173186
if err != nil && !errors.Is(err, netlink.ErrDumpInterrupted) {
174-
klog.Infof("fail to get ip addresses for interface %s : %v", ifName, err)
187+
errorList = append(errorList, fmt.Errorf("fail to get ip addresses for interface %s : %w", ifName, err))
175188
} else {
176189
for _, address := range nlAddresses {
177190
// Only move IP addresses with global scope because those are not host-specific, auto-configured,
@@ -185,21 +198,6 @@ func (np *NetworkDriver) prepareResourceClaim(ctx context.Context, claim *resour
185198
}
186199
}
187200

188-
// If there are no addresses configured on the interface and the user is not setting them
189-
// this may be an interface that uses DHCP, so we bring it up if necessary and do a DHCP
190-
// request to gather the network parameters (IPs and Routes) ... but we DO NOT apply them
191-
// in the root namespace
192-
if len(podCfg.Network.Interface.Addresses) == 0 {
193-
klog.V(2).Infof("trying to get network configuration via DHCP")
194-
ip, routes, err := getDHCP(ifName)
195-
if err != nil {
196-
klog.Infof("fail to get configuration via DHCP: %v", err)
197-
} else {
198-
podCfg.Network.Interface.Addresses = []string{ip}
199-
podCfg.Network.Routes = append(podCfg.Network.Routes, routes...)
200-
}
201-
}
202-
203201
// Obtain the existing supported ethtool features and validate the config
204202
if podCfg.Network.Ethtool != nil {
205203
client, err := newEthtoolClient(0)

0 commit comments

Comments
 (0)