mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-31 23:37:01 +00:00
kubenet set cbr0 mac address
This commit is contained in:
parent
87ab70d6ef
commit
950e689637
@ -45,6 +45,7 @@ import (
|
||||
utilsysctl "k8s.io/kubernetes/pkg/util/sysctl"
|
||||
|
||||
"k8s.io/kubernetes/pkg/kubelet/network/hostport"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
const (
|
||||
@ -56,6 +57,9 @@ const (
|
||||
|
||||
// fallbackMTU is used if an MTU is not specified, and we cannot determine the MTU
|
||||
fallbackMTU = 1460
|
||||
|
||||
// private mac prefix safe to use
|
||||
privateMACPrefix = "0a:58"
|
||||
)
|
||||
|
||||
type kubenetNetworkPlugin struct {
|
||||
@ -79,6 +83,8 @@ type kubenetNetworkPlugin struct {
|
||||
// kubenet will search for cni binaries in DefaultCNIDir first, then continue to vendorDir.
|
||||
vendorDir string
|
||||
nonMasqueradeCIDR string
|
||||
podCidr string
|
||||
gateway net.IP
|
||||
}
|
||||
|
||||
func NewPlugin(networkPluginDir string) network.NetworkPlugin {
|
||||
@ -243,6 +249,8 @@ func (plugin *kubenetNetworkPlugin) Event(name string, details map[string]interf
|
||||
// plugin will bail out if the bridge has an unexpected one
|
||||
plugin.clearBridgeAddressesExcept(cidr)
|
||||
}
|
||||
plugin.podCidr = podCIDR
|
||||
plugin.gateway = cidr.IP
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
@ -327,6 +335,23 @@ func (plugin *kubenetNetworkPlugin) setup(namespace string, name string, id kube
|
||||
return fmt.Errorf("CNI plugin reported an invalid IPv4 address for container %v: %+v.", id, res.IP4)
|
||||
}
|
||||
|
||||
|
||||
// Explicitly assign mac address to cbr0. If bridge mac address is not explicitly set will adopt the lowest MAC address of the attached veths.
|
||||
// TODO: Remove this once upstream cni bridge plugin handles this
|
||||
link, err := netlink.LinkByName(BridgeName)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to lookup %q: %v", BridgeName, err)
|
||||
}
|
||||
macAddr, err := generateHardwareAddr(plugin.gateway)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
glog.V(3).Infof("Configure %q mac address to %v", BridgeName, macAddr)
|
||||
err = netlink.LinkSetHardwareAddr(link, macAddr)
|
||||
if err != nil {
|
||||
return fmt.Errorf("Failed to configure %q mac address to %q: %v", BridgeName, macAddr, err)
|
||||
}
|
||||
|
||||
// Put the container bridge into promiscuous mode to force it to accept hairpin packets.
|
||||
// TODO: Remove this once the kernel bug (#20096) is fixed.
|
||||
// TODO: check and set promiscuous mode with netlink once vishvananda/netlink supports it
|
||||
@ -338,6 +363,8 @@ func (plugin *kubenetNetworkPlugin) setup(namespace string, name string, id kube
|
||||
return fmt.Errorf("Error setting promiscuous mode on %s: %v", BridgeName, err)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
// The first SetUpPod call creates the bridge; get a shaper for the sake of
|
||||
@ -583,3 +610,21 @@ func (plugin *kubenetNetworkPlugin) shaper() bandwidth.BandwidthShaper {
|
||||
}
|
||||
return plugin.bandwidthShaper
|
||||
}
|
||||
|
||||
// generateHardwareAddr generates 48 bit virtual mac addresses based on the IP input.
|
||||
func generateHardwareAddr(ip net.IP) (net.HardwareAddr, error) {
|
||||
if ip.To4() == nil {
|
||||
return nil, fmt.Errorf("generateHardwareAddr only support valid ipv4 address as input")
|
||||
}
|
||||
mac := privateMACPrefix
|
||||
sections := strings.Split(ip.String(), ".")
|
||||
for _, s := range sections {
|
||||
i, _ := strconv.Atoi(s)
|
||||
mac = mac + ":" + fmt.Sprintf("%02x", i)
|
||||
}
|
||||
hwAddr, err := net.ParseMAC(mac)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("Failed to parse mac address %s generated based on ip %s due to: %v", mac, ip, err)
|
||||
}
|
||||
return hwAddr, nil
|
||||
}
|
@ -18,6 +18,7 @@ package kubenet
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/mock"
|
||||
@ -198,4 +199,34 @@ func TestInit_MTU(t *testing.T) {
|
||||
assert.Equal(t, 1, sysctl.Settings["net/bridge/bridge-nf-call-iptables"], "net/bridge/bridge-nf-call-iptables sysctl should have been set")
|
||||
}
|
||||
|
||||
func TestGenerateMacAddress(t *testing.T) {
|
||||
testCases := []struct {
|
||||
ip net.IP
|
||||
expectedMAC string
|
||||
}{
|
||||
{
|
||||
ip: net.ParseIP("10.0.0.2"),
|
||||
expectedMAC: privateMACPrefix + ":0a:00:00:02",
|
||||
},
|
||||
{
|
||||
ip: net.ParseIP("10.250.0.244"),
|
||||
expectedMAC: privateMACPrefix + ":0a:fa:00:f4",
|
||||
},
|
||||
{
|
||||
ip: net.ParseIP("172.17.0.2"),
|
||||
expectedMAC: privateMACPrefix + ":ac:11:00:02",
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range testCases {
|
||||
mac, err := generateHardwareAddr(tc.ip)
|
||||
if err != nil {
|
||||
t.Errorf("Did not expect error: %v", err)
|
||||
}
|
||||
if mac.String() != tc.expectedMAC {
|
||||
t.Errorf("generated mac: %q, expecting: %q", mac.String(), tc.expectedMAC)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//TODO: add unit test for each implementation of network plugin interface
|
||||
|
Loading…
Reference in New Issue
Block a user