Skip to content
This repository has been archived by the owner on Jul 1, 2023. It is now read-only.

Commit

Permalink
vxlan: Generate MAC address before creating a link
Browse files Browse the repository at this point in the history
systemd 242+ assigns MAC addresses for all virtual devices which don't
have the address assigned already. That resulted in systemd overriding
MAC addresses of flannel.* interfaces. The fix which prevents systemd
from setting the address is to define the concrete MAC address when
creating the link.

Fixes: flannel-io#1155
Ref: k3s-io/k3s#4188
Signed-off-by: Michal Rostecki <mrostecki@opensuse.org>
  • Loading branch information
vadorovsky committed Oct 15, 2021
1 parent 154ea8e commit 0198d5d
Show file tree
Hide file tree
Showing 3 changed files with 72 additions and 3 deletions.
12 changes: 9 additions & 3 deletions backend/vxlan/device.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// +build !windows

package vxlan

Expand All @@ -24,6 +23,7 @@ import (

"github.com/containernetworking/plugins/pkg/utils/sysctl"
"github.com/flannel-io/flannel/pkg/ip"
"github.com/flannel-io/flannel/pkg/mac"
"github.com/vishvananda/netlink"
log "k8s.io/klog"
)
Expand All @@ -44,9 +44,15 @@ type vxlanDevice struct {
}

func newVXLANDevice(devAttrs *vxlanDeviceAttrs) (*vxlanDevice, error) {
hardwareAddr, err := mac.NewHardwareAddr()
if err != nil {
return nil, err
}

link := &netlink.Vxlan{
LinkAttrs: netlink.LinkAttrs{
Name: devAttrs.name,
Name: devAttrs.name,
HardwareAddr: hardwareAddr,
},
VxlanId: int(devAttrs.vni),
VtepDevIndex: devAttrs.vtepIndex,
Expand All @@ -56,7 +62,7 @@ func newVXLANDevice(devAttrs *vxlanDeviceAttrs) (*vxlanDevice, error) {
GBP: devAttrs.gbp,
}

link, err := ensureLink(link)
link, err = ensureLink(link)
if err != nil {
return nil, err
}
Expand Down
35 changes: 35 additions & 0 deletions pkg/mac/mac.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
// Copyright 2021 flannel authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package mac

import (
"crypto/rand"
"fmt"
"net"
)

// NewHardwareAddr generates a new random hardware (MAC) address, local and
// unicast.
func NewHardwareAddr() (net.HardwareAddr, error) {
hardwareAddr := make(net.HardwareAddr, 6)
if _, err := rand.Read(hardwareAddr); err != nil {
return nil, fmt.Errorf("could not generate random MAC address: %w", err)
}

// Ensure that address is locally administered and unicast.
hardwareAddr[0] = (hardwareAddr[0] & 0xfe) | 0x02

return hardwareAddr, nil
}
28 changes: 28 additions & 0 deletions pkg/mac/mac_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
// Copyright 2021 flannel authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package mac

import (
"testing"
)

func TestNewHardwareAddr(t *testing.T) {
// Ignore the actual address, since it's random.
// But an error should never be returned.
_, err := NewHardwareAddr()
if err != nil {
t.Fatalf(err)
}
}

0 comments on commit 0198d5d

Please sign in to comment.