Skip to content

Commit 20d2f1b

Browse files
committed
query host to check if dhcp rehydration feature is enabled and skip sending workaround dhcp request if so
1 parent bbe5cb9 commit 20d2f1b

File tree

4 files changed

+64
-5
lines changed

4 files changed

+64
-5
lines changed

dhcp/dhcp_linux.go

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@ import (
1010
"encoding/binary"
1111
"io"
1212
"net"
13+
"net/http"
14+
"strings"
1315
"time"
1416

1517
"github.com/pkg/errors"
@@ -37,6 +39,9 @@ const (
3739
hops = 0
3840
secs = 0
3941
flags = 0x8000 // Broadcast flag
42+
43+
nmAgentSupportedApisURL = "http://168.63.129.16/machine/plugins/?comp=nmagent&type=GetSupportedApis"
44+
dhcpRehydrationAPIStr = "SwiftV2DhcpRehydrationFromGoalState" // Set value provided by host
4045
)
4146

4247
// TransactionID represents a 4-byte DHCP transaction ID as defined in RFC 951,
@@ -49,6 +54,8 @@ var (
4954
magicCookie = []byte{0x63, 0x82, 0x53, 0x63} // DHCP magic cookie
5055
DefaultReadTimeout = 3 * time.Second
5156
DefaultTimeout = 3 * time.Second
57+
58+
errResponseNotOK = errors.New("not ok http status")
5259
)
5360

5461
type DHCP struct {
@@ -459,3 +466,37 @@ func (c *DHCP) DiscoverRequest(ctx context.Context, mac net.HardwareAddr, ifname
459466
res := c.receiveDHCPResponse(ctx, reader, txid)
460467
return res
461468
}
469+
470+
// DHCPRehydrationFeatureOnHost queries the host to check if a particular API is supported,
471+
// and if so, returns true; if we are unable to determine if the feature is enabled, an error
472+
// is returned
473+
func (c *DHCP) DHCPRehydrationFeatureOnHost(ctx context.Context) (bool, error) {
474+
var (
475+
resp *http.Response
476+
httpClient = &http.Client{Timeout: DefaultTimeout}
477+
)
478+
req, err := http.NewRequestWithContext(ctx, http.MethodGet, nmAgentSupportedApisURL, nil)
479+
if err != nil {
480+
return false, errors.Wrap(err, "failed to create http request")
481+
}
482+
req.Header.Add("Metadata", "true")
483+
req.Header.Add("x-ms-version", "2012-11-30")
484+
resp, err = httpClient.Do(req)
485+
if err != nil {
486+
return false, errors.Wrap(err, "error issuing http request")
487+
}
488+
defer resp.Body.Close()
489+
if resp.StatusCode != http.StatusOK {
490+
return false, errResponseNotOK
491+
}
492+
bytes, err := io.ReadAll(resp.Body)
493+
if err != nil {
494+
return false, errors.Wrap(err, "failed to read response body")
495+
}
496+
str := string(bytes)
497+
if !strings.Contains(str, dhcpRehydrationAPIStr) {
498+
return false, nil
499+
}
500+
501+
return true, nil
502+
}

dhcp/dhcp_windows.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,3 +20,7 @@ func New(logger *zap.Logger) *DHCP {
2020
func (c *DHCP) DiscoverRequest(_ context.Context, _ net.HardwareAddr, _ string) error {
2121
return nil
2222
}
23+
24+
func (c *DHCP) DHCPRehydrationFeatureOnHost(ctx context.Context) (bool, error) {
25+
return false, nil
26+
}

network/dhcp.go

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,15 @@ import (
77

88
type dhcpClient interface {
99
DiscoverRequest(context.Context, net.HardwareAddr, string) error
10+
DHCPRehydrationFeatureOnHost(context.Context) (bool, error)
1011
}
1112

1213
type mockDHCP struct{}
1314

14-
func (netns *mockDHCP) DiscoverRequest(context.Context, net.HardwareAddr, string) error {
15+
func (d *mockDHCP) DiscoverRequest(context.Context, net.HardwareAddr, string) error {
1516
return nil
1617
}
18+
19+
func (d *mockDHCP) DHCPRehydrationFeatureOnHost(context.Context) (bool, error) {
20+
return false, nil
21+
}

network/secondary_endpoint_client_linux.go

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -138,12 +138,21 @@ func (client *SecondaryEndpointClient) ConfigureContainerInterfacesAndRoutes(epI
138138
timeout := time.Duration(numSecs) * time.Second
139139
ctx, cancel := context.WithDeadline(context.Background(), time.Now().Add(timeout))
140140
defer cancel()
141-
logger.Info("Sending DHCP packet", zap.Any("macAddress", epInfo.MacAddress), zap.String("ifName", epInfo.IfName))
142-
err := client.dhcpClient.DiscoverRequest(ctx, epInfo.MacAddress, epInfo.IfName)
141+
142+
// check if the permanent fix on the host has already rolled out
143+
dhcpRehydrationFeatureEnabled, err := client.dhcpClient.DHCPRehydrationFeatureOnHost(ctx)
143144
if err != nil {
144-
return errors.Wrapf(err, "failed to issue dhcp discover packet to create mapping in host")
145+
return errors.Wrap(err, "could not determine if dhcp rehydration feature enabled on host")
146+
}
147+
// only send the dhcp packet if the host does not have the permanent fix
148+
if !dhcpRehydrationFeatureEnabled {
149+
logger.Info("Sending DHCP packet", zap.Any("macAddress", epInfo.MacAddress), zap.String("ifName", epInfo.IfName))
150+
err := client.dhcpClient.DiscoverRequest(ctx, epInfo.MacAddress, epInfo.IfName)
151+
if err != nil {
152+
return errors.Wrap(err, "failed to issue dhcp discover packet to create mapping in host")
153+
}
154+
logger.Info("Finished configuring container interfaces and routes for secondary endpoint client")
145155
}
146-
logger.Info("Finished configuring container interfaces and routes for secondary endpoint client")
147156

148157
return nil
149158
}

0 commit comments

Comments
 (0)