Fix random veth MAC address being reset

This commit is contained in:
Jack O'Sullivan 2021-06-08 17:58:12 +01:00
parent f6e0d0b7b7
commit b250b7ecb1

View File

@ -179,8 +179,15 @@ func (p *Plugin) CreateEndpoint(ctx context.Context, r CreateEndpointRequest) (C
if err := netlink.LinkSetUp(ctrLink); err != nil { if err := netlink.LinkSetUp(ctrLink); err != nil {
return fmt.Errorf("failed to set container side link of veth pair up: %w", err) return fmt.Errorf("failed to set container side link of veth pair up: %w", err)
} }
// Only write back the MAC address if it wasn't provided to us by libnetwork
if r.Interface.MacAddress == "" { if r.Interface.MacAddress == "" {
// Only write back the MAC address if it wasn't provided to us by libnetwork // The kernel will often reset a randomly assigned MAC address after actions like LinkSetMaster. We prevent
// this behaviour by setting it manually to the random value
if err := netlink.LinkSetHardwareAddr(ctrLink, ctrLink.Attrs().HardwareAddr); err != nil {
return fmt.Errorf("failed to set container side of veth pair's MAC address: %w", err)
}
res.Interface.MacAddress = ctrLink.Attrs().HardwareAddr.String() res.Interface.MacAddress = ctrLink.Attrs().HardwareAddr.String()
} }
@ -193,20 +200,21 @@ func (p *Plugin) CreateEndpoint(ctx context.Context, r CreateEndpointRequest) (C
timeout = opts.LeaseTimeout timeout = opts.LeaseTimeout
} }
initialIP := func(v6 bool) error { initialIP := func(v6 bool) error {
v6str := ""
if v6 {
v6str = "v6"
}
timeoutCtx, cancel := context.WithTimeout(ctx, timeout) timeoutCtx, cancel := context.WithTimeout(ctx, timeout)
defer cancel() defer cancel()
info, err := udhcpc.GetIP(timeoutCtx, ctrName, &udhcpc.DHCPClientOptions{V6: v6}) info, err := udhcpc.GetIP(timeoutCtx, ctrName, &udhcpc.DHCPClientOptions{V6: v6})
if err != nil { if err != nil {
v6str := ""
if v6 {
v6str = "v6"
}
return fmt.Errorf("failed to get initial IP%v address via DHCP%v: %w", v6str, v6str, err) return fmt.Errorf("failed to get initial IP%v address via DHCP%v: %w", v6str, v6str, err)
} }
ip, _, err := net.ParseCIDR(info.IP) ip, _, err := net.ParseCIDR(info.IP)
if err != nil { if err != nil {
return fmt.Errorf("failed to parse initial IP address: %w", err) return fmt.Errorf("failed to parse initial IP%v address: %w", v6str, err)
} }
hint := p.joinHints[r.EndpointID] hint := p.joinHints[r.EndpointID]
@ -241,11 +249,12 @@ func (p *Plugin) CreateEndpoint(ctx context.Context, r CreateEndpointRequest) (C
} }
log.WithFields(log.Fields{ log.WithFields(log.Fields{
"network": r.NetworkID[:12], "network": r.NetworkID[:12],
"endpoint": r.EndpointID[:12], "endpoint": r.EndpointID[:12],
"ip": res.Interface.Address, "mac_address": res.Interface.MacAddress,
"ipv6": res.Interface.AddressIPv6, "ip": res.Interface.Address,
"gateway": fmt.Sprintf("%#v", p.joinHints[r.EndpointID].Gateway), "ipv6": res.Interface.AddressIPv6,
"gateway": fmt.Sprintf("%#v", p.joinHints[r.EndpointID].Gateway),
}).Info("Endpoint created") }).Info("Endpoint created")
return res, nil return res, nil