Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion internal/server/device/nic_macvlan.go
Original file line number Diff line number Diff line change
Expand Up @@ -219,7 +219,7 @@ func (d *nicMACVLAN) Start() (*deviceConfig.RunConfig, error) {

if d.inst.Type() == instancetype.VM {
// Enable all multicast processing which is required for IPv6 NDP functionality.
link.AllMutlicast = true
link.AllMulticast = true

// Bring the interface up on host side.
link.Up = true
Expand Down
60 changes: 58 additions & 2 deletions internal/server/ip/link.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,15 +17,30 @@ import (
// Link represents base arguments for link device.
type Link struct {
Name string
Kind string
MTU uint32
Parent string
Address net.HardwareAddr
TXQueueLength uint32
AllMutlicast bool
AllMulticast bool
Master string
Up bool
}

type jsonLink struct {
Name string `json:"ifname"`
MTU uint32 `json:"mtu"`
Parent string `json:"link"`
Address string `json:"address"`
TXQueueLength uint32 `json:"txqlen"`
AllMulticast int `json:"allmulti"`
Master string `json:"master"`
Up string `json:"operstate"`
Info struct {
Kind string `json:"info_kind"`
} `json:"linkinfo"`
}

// args generate common arguments for the virtual link.
func (l *Link) args() []string {
var result []string
Expand All @@ -50,7 +65,7 @@ func (l *Link) args() []string {
result = append(result, "txqueuelen", fmt.Sprintf("%d", l.TXQueueLength))
}

if l.AllMutlicast {
if l.AllMulticast {
result = append(result, "allmulticast", "on")
}

Expand Down Expand Up @@ -79,6 +94,47 @@ func (l *Link) add(linkType string, additionalArgs []string) error {
return nil
}

// LinkFromName returns a Link from a device name.
func LinkFromName(name string) (*Link, error) {
out, err := subprocess.RunCommand("ip", "-d", "-j", "link", "show", name)
if err != nil {
return nil, err
}

var links []jsonLink
err = json.Unmarshal([]byte(out), &links)
if err != nil {
return nil, fmt.Errorf("failed to decode JSON link representation: %w", err)
}

jl := &links[0]
l := &Link{
Name: jl.Name,
Kind: jl.Info.Kind,
MTU: jl.MTU,
Parent: jl.Parent,
TXQueueLength: jl.TXQueueLength,
Master: jl.Master,
}

if jl.Address != "" {
l.Address, err = net.ParseMAC(jl.Address)
if err != nil {
return nil, err
}
}

if jl.AllMulticast == 1 {
l.AllMulticast = true
}

if jl.Up == "UP" {
l.Up = true
}

return l, err
}

// SetUp enables the link device.
func (l *Link) SetUp() error {
_, err := subprocess.RunCommand("ip", "link", "set", "dev", l.Name, "up")
Expand Down
20 changes: 13 additions & 7 deletions internal/server/network/driver_bridge.go
Original file line number Diff line number Diff line change
Expand Up @@ -671,14 +671,20 @@ func (n *bridge) setup(oldConfig map[string]string) error {
return err
}

// Cleanup any existing tunnel device.
// Cleanup any existing tunnel and dummy devices.
for _, iface := range ifaces {
if strings.HasPrefix(iface.Name, fmt.Sprintf("%s-", n.name)) {
tunLink := &ip.Link{Name: iface.Name}
err = tunLink.Delete()
if err != nil {
return err
}
l, err := ip.LinkFromName(iface.Name)
if err != nil {
return err
}

if l.Master != n.name || l.Kind != "vxlan" && l.Kind != "gretap" && l.Kind != "dummy" {
continue
}

err = l.Delete()
if err != nil {
return err
}
}

Expand Down