diff --git a/internal/server/network/ovs/ovs_actions.go b/internal/server/network/ovs/ovs_actions.go index f3b95dc8667..5ac387a7bed 100644 --- a/internal/server/network/ovs/ovs_actions.go +++ b/internal/server/network/ovs/ovs_actions.go @@ -10,6 +10,7 @@ import ( ovsdbClient "github.com/ovn-org/libovsdb/client" ovsdbModel "github.com/ovn-org/libovsdb/model" + "github.com/ovn-org/libovsdb/ovsdb" "github.com/lxc/incus/internal/server/ip" ovsSwitch "github.com/lxc/incus/internal/server/network/ovs/schema/ovs" @@ -44,23 +45,83 @@ func (o *VSwitch) BridgeExists(bridgeName string) (bool, error) { // BridgeAdd adds a new bridge. func (o *VSwitch) BridgeAdd(bridgeName string, mayExist bool, hwaddr net.HardwareAddr, mtu uint32) error { - args := []string{} + ctx := context.TODO() - if mayExist { - args = append(args, "--may-exist") + // Interface + iface := ovsSwitch.Interface{ + UUID: "interface", + Name: bridgeName, + } + + if mtu > 0 { + mtu := int(mtu) + iface.MTURequest = &mtu + } + + interfaceOps, err := o.client.Create(&iface) + if err != nil { + return err + } + + // Port + port := ovsSwitch.Port{ + UUID: "port", + Name: bridgeName, + Interfaces: []string{"interface"}, } - args = append(args, "add-br", bridgeName) + portOps, err := o.client.Create(&port) + if err != nil { + return err + } + + //// Bridge + bridge := ovsSwitch.Bridge{ + UUID: "bridge", + Name: bridgeName, + Ports: []string{port.UUID}, + } if hwaddr != nil { - args = append(args, "--", "set", "bridge", bridgeName, fmt.Sprintf(`other-config:hwaddr="%s"`, hwaddr.String())) + bridge.OtherConfig = map[string]string{"hwaddr": hwaddr.String()} } - if mtu > 0 { - args = append(args, "--", "set", "int", bridgeName, fmt.Sprintf(`mtu_request=%d`, mtu)) + bridgeOps, err := o.client.Create(&bridge) + if err != nil { + return err } - _, err := subprocess.RunCommand("ovs-vsctl", args...) + if mayExist { + err = o.client.Get(ctx, &bridge) + if err != nil && err != ovsdbClient.ErrNotFound { + return err + } + + if bridge.UUID != "" { + // Bridge already exists. + return nil + } + } + + //// Switch entry + ovsRow := ovsSwitch.OpenvSwitch{ + UUID: o.rootUUID, + } + + mutateOps, err := o.client.Where(&ovsRow).Mutate(&ovsRow, ovsdbModel.Mutation{ + Field: &ovsRow.Bridges, + Mutator: ovsdb.MutateOperationInsert, + Value: []string{bridge.UUID}, + }) + if err != nil { + return err + } + + operations := append(interfaceOps, portOps...) + operations = append(operations, bridgeOps...) + operations = append(operations, mutateOps...) + + _, err = o.client.Transact(ctx, operations...) if err != nil { return err }