Skip to content

Commit e4ab5bd

Browse files
committed
Create the bridges for bonds and vlans.
This should be all wired up.
1 parent bf19ca0 commit e4ab5bd

File tree

3 files changed

+275
-27
lines changed

3 files changed

+275
-27
lines changed

network/netplan/activate.go

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -58,10 +58,18 @@ func BridgeAndActivate(params ActivationParams) (*ActivationResult, error) {
5858
if err != nil {
5959
return nil, err
6060
}
61-
// case TypeBond:
62-
// case TypeVLAN:
61+
case TypeBond:
62+
err = netplan.BridgeBondById(deviceId, device.BridgeName)
63+
if err != nil {
64+
return nil, err
65+
}
66+
case TypeVLAN:
67+
err = netplan.BridgeVLANById(deviceId, device.BridgeName)
68+
if err != nil {
69+
return nil, err
70+
}
6371
default:
64-
return nil, errors.Errorf("don't know how to bridge the device %q of type %q", deviceId, deviceType)
72+
return nil, errors.Errorf("unable to create bridge for %q, unknown device type %q", deviceId, deviceType)
6573
}
6674
}
6775
_, err = netplan.Write("")

network/netplan/netplan.go

Lines changed: 65 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -185,41 +185,91 @@ type BondParameters struct {
185185
Primary string `yaml:"primary,omitempty"`
186186
}
187187

188-
// BridgeDeviceById takes a deviceId and creates a bridge with this device
188+
// BridgeEthernetById takes a deviceId and creates a bridge with this device
189189
// using this devices config
190190
func (np *Netplan) BridgeEthernetById(deviceId string, bridgeName string) (err error) {
191191
ethernet, ok := np.Network.Ethernets[deviceId]
192192
if !ok {
193-
return errors.NotFoundf("Device with id %q for bridge %q", deviceId, bridgeName)
193+
return errors.NotFoundf("ethernet device with id %q for bridge %q", deviceId, bridgeName)
194194
}
195+
shouldCreate, err := np.shouldCreateBridge(deviceId, bridgeName)
196+
if !shouldCreate {
197+
// err may be nil, but we shouldn't continue creating
198+
return errors.Trace(err)
199+
}
200+
np.createBridgeFromInterface(bridgeName, deviceId, &ethernet.Interface)
201+
np.Network.Ethernets[deviceId] = ethernet
202+
return nil
203+
}
204+
205+
// BridgeVLANById takes a deviceId and creates a bridge with this device
206+
// using this devices config
207+
func (np *Netplan) BridgeVLANById(deviceId string, bridgeName string) (err error) {
208+
vlan, ok := np.Network.VLANs[deviceId]
209+
if !ok {
210+
return errors.NotFoundf("VLAN device with id %q for bridge %q", deviceId, bridgeName)
211+
}
212+
shouldCreate, err := np.shouldCreateBridge(deviceId, bridgeName)
213+
if !shouldCreate {
214+
// err may be nil, but we shouldn't continue creating
215+
return errors.Trace(err)
216+
}
217+
np.createBridgeFromInterface(bridgeName, deviceId, &vlan.Interface)
218+
np.Network.VLANs[deviceId] = vlan
219+
return nil
220+
}
221+
222+
// BridgeBondById takes a deviceId and creates a bridge with this device
223+
// using this devices config
224+
func (np *Netplan) BridgeBondById(deviceId string, bridgeName string) (err error) {
225+
bond, ok := np.Network.Bonds[deviceId]
226+
if !ok {
227+
return errors.NotFoundf("bond device with id %q for bridge %q", deviceId, bridgeName)
228+
}
229+
shouldCreate, err := np.shouldCreateBridge(deviceId, bridgeName)
230+
if !shouldCreate {
231+
// err may be nil, but we shouldn't continue creating
232+
return errors.Trace(err)
233+
}
234+
np.createBridgeFromInterface(bridgeName, deviceId, &bond.Interface)
235+
np.Network.Bonds[deviceId] = bond
236+
return nil
237+
}
238+
239+
// shouldCreateBridge returns true only if it is clear the bridge doesn't already exist, and that the existing device
240+
// isn't in a different bridge.
241+
func (np *Netplan) shouldCreateBridge(deviceId string, bridgeName string) (bool, error) {
195242
for bName, bridge := range np.Network.Bridges {
196243
for _, i := range bridge.Interfaces {
197244
if i == deviceId {
198-
// The device is already properly bridged, we're not doing anything
245+
// The device is already properly bridged, nothing to do
199246
if bridgeName == bName {
200-
return nil
247+
return false, nil
201248
} else {
202-
return errors.AlreadyExistsf("Device %q is already bridged in bridge %q instead of %q", deviceId, bName, bridgeName)
249+
return false, errors.AlreadyExistsf("cannot create bridge %q, device %q in bridge %q", bridgeName, deviceId, bName)
203250
}
204251
}
205252
}
206253
if bridgeName == bName {
207-
return errors.AlreadyExistsf("Cannot bridge device %q on bridge %q - bridge named %q", deviceId, bridgeName, bridgeName)
254+
return false, errors.AlreadyExistsf(
255+
"cannot create bridge %q with device %q - bridge %q w/ interfaces %q",
256+
bridgeName, deviceId, bridgeName, strings.Join(bridge.Interfaces, ", "))
208257
}
209258
}
210-
// copy aside and clear the IP settings from the original Ethernet device, except for MTU
211-
intf := ethernet.Interface
212-
ethernet.Interface = Interface{MTU: intf.MTU}
213-
// create a bridge
259+
return true, nil
260+
}
261+
262+
// createBridgeFromInterface will create a bridge stealing the interface details, and wiping the existing interface
263+
// except for MTU so that IP Address information is never duplicated.
264+
func (np *Netplan) createBridgeFromInterface(bridgeName, deviceId string, intf *Interface) {
214265
if np.Network.Bridges == nil {
215266
np.Network.Bridges = make(map[string]Bridge)
216267
}
217268
np.Network.Bridges[bridgeName] = Bridge{
218269
Interfaces: []string{deviceId},
219-
Interface: intf,
270+
Interface: *intf,
220271
}
221-
np.Network.Ethernets[deviceId] = ethernet
222-
return nil
272+
*intf = Interface{MTU: intf.MTU}
223273
}
224274

225275
func Unmarshal(in []byte, out interface{}) (err error) {
@@ -410,14 +460,14 @@ func (np *Netplan) FindBondByMAC(mac string) (device string, err error) {
410460
return id, nil
411461
}
412462
}
413-
return "", errors.NotFoundf("Bond device with MAC %q", mac)
463+
return "", errors.NotFoundf("bond device with MAC %q", mac)
414464
}
415465

416466
func (np *Netplan) FindBondByName(name string) (device string, err error) {
417467
if _, ok := np.Network.Bonds[name]; ok {
418468
return name, nil
419469
}
420-
return "", errors.NotFoundf("Bond device with name %q", name)
470+
return "", errors.NotFoundf("bond device with name %q", name)
421471
}
422472

423473
type DeviceType string

0 commit comments

Comments
 (0)