snapshot: sagernet/gvisor v0.0.0-20250811.0-sing-box-mod.1
Содержимое пина, зафиксированного в go.mod sing-box-lx, одним коммитом без истории. Полная история SagerNet/gvisor — 1.45 ГБ и клонируется в каждой CI-джобе; наша дельта — одна вставка в одну функцию, история для неё не нужна. Module path github.com/sagernet/gvisor сохранён намеренно: на него опирается replace-директива суперпроекта. Патч поверх — отдельным коммитом, чтобы дельта читалась одним git show и переносилась на новый пин копированием. SPECS/TASKS/048-GVISOR_HANDSHAKE_NIL_CRASH
This commit is contained in:
commit
2c4ae3b0a4
712 changed files with 185689 additions and 0 deletions
2
.gitignore
vendored
Normal file
2
.gitignore
vendored
Normal file
|
|
@ -0,0 +1,2 @@
|
||||||
|
/.idea/
|
||||||
|
.DS_Store
|
||||||
8
AUTHORS
Normal file
8
AUTHORS
Normal file
|
|
@ -0,0 +1,8 @@
|
||||||
|
# This is the list of gVisor authors for copyright purposes.
|
||||||
|
#
|
||||||
|
# This does not necessarily list everyone who has contributed code, since in
|
||||||
|
# some cases, their employer may be the copyright holder. To see the full list
|
||||||
|
# of contributors, see the revision history in source control.
|
||||||
|
#
|
||||||
|
# Please send a patch if you would like to be included in this list.
|
||||||
|
Google LLC
|
||||||
254
LICENSE
Normal file
254
LICENSE
Normal file
|
|
@ -0,0 +1,254 @@
|
||||||
|
|
||||||
|
Apache License
|
||||||
|
Version 2.0, January 2004
|
||||||
|
http://www.apache.org/licenses/
|
||||||
|
|
||||||
|
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||||
|
|
||||||
|
1. Definitions.
|
||||||
|
|
||||||
|
"License" shall mean the terms and conditions for use, reproduction,
|
||||||
|
and distribution as defined by Sections 1 through 9 of this document.
|
||||||
|
|
||||||
|
"Licensor" shall mean the copyright owner or entity authorized by
|
||||||
|
the copyright owner that is granting the License.
|
||||||
|
|
||||||
|
"Legal Entity" shall mean the union of the acting entity and all
|
||||||
|
other entities that control, are controlled by, or are under common
|
||||||
|
control with that entity. For the purposes of this definition,
|
||||||
|
"control" means (i) the power, direct or indirect, to cause the
|
||||||
|
direction or management of such entity, whether by contract or
|
||||||
|
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||||
|
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||||
|
|
||||||
|
"You" (or "Your") shall mean an individual or Legal Entity
|
||||||
|
exercising permissions granted by this License.
|
||||||
|
|
||||||
|
"Source" form shall mean the preferred form for making modifications,
|
||||||
|
including but not limited to software source code, documentation
|
||||||
|
source, and configuration files.
|
||||||
|
|
||||||
|
"Object" form shall mean any form resulting from mechanical
|
||||||
|
transformation or translation of a Source form, including but
|
||||||
|
not limited to compiled object code, generated documentation,
|
||||||
|
and conversions to other media types.
|
||||||
|
|
||||||
|
"Work" shall mean the work of authorship, whether in Source or
|
||||||
|
Object form, made available under the License, as indicated by a
|
||||||
|
copyright notice that is included in or attached to the work
|
||||||
|
(an example is provided in the Appendix below).
|
||||||
|
|
||||||
|
"Derivative Works" shall mean any work, whether in Source or Object
|
||||||
|
form, that is based on (or derived from) the Work and for which the
|
||||||
|
editorial revisions, annotations, elaborations, or other modifications
|
||||||
|
represent, as a whole, an original work of authorship. For the purposes
|
||||||
|
of this License, Derivative Works shall not include works that remain
|
||||||
|
separable from, or merely link (or bind by name) to the interfaces of,
|
||||||
|
the Work and Derivative Works thereof.
|
||||||
|
|
||||||
|
"Contribution" shall mean any work of authorship, including
|
||||||
|
the original version of the Work and any modifications or additions
|
||||||
|
to that Work or Derivative Works thereof, that is intentionally
|
||||||
|
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||||
|
or by an individual or Legal Entity authorized to submit on behalf of
|
||||||
|
the copyright owner. For the purposes of this definition, "submitted"
|
||||||
|
means any form of electronic, verbal, or written communication sent
|
||||||
|
to the Licensor or its representatives, including but not limited to
|
||||||
|
communication on electronic mailing lists, source code control systems,
|
||||||
|
and issue tracking systems that are managed by, or on behalf of, the
|
||||||
|
Licensor for the purpose of discussing and improving the Work, but
|
||||||
|
excluding communication that is conspicuously marked or otherwise
|
||||||
|
designated in writing by the copyright owner as "Not a Contribution."
|
||||||
|
|
||||||
|
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||||
|
on behalf of whom a Contribution has been received by Licensor and
|
||||||
|
subsequently incorporated within the Work.
|
||||||
|
|
||||||
|
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||||
|
this License, each Contributor hereby grants to You a perpetual,
|
||||||
|
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||||
|
copyright license to reproduce, prepare Derivative Works of,
|
||||||
|
publicly display, publicly perform, sublicense, and distribute the
|
||||||
|
Work and such Derivative Works in Source or Object form.
|
||||||
|
|
||||||
|
3. Grant of Patent License. Subject to the terms and conditions of
|
||||||
|
this License, each Contributor hereby grants to You a perpetual,
|
||||||
|
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||||
|
(except as stated in this section) patent license to make, have made,
|
||||||
|
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||||
|
where such license applies only to those patent claims licensable
|
||||||
|
by such Contributor that are necessarily infringed by their
|
||||||
|
Contribution(s) alone or by combination of their Contribution(s)
|
||||||
|
with the Work to which such Contribution(s) was submitted. If You
|
||||||
|
institute patent litigation against any entity (including a
|
||||||
|
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||||
|
or a Contribution incorporated within the Work constitutes direct
|
||||||
|
or contributory patent infringement, then any patent licenses
|
||||||
|
granted to You under this License for that Work shall terminate
|
||||||
|
as of the date such litigation is filed.
|
||||||
|
|
||||||
|
4. Redistribution. You may reproduce and distribute copies of the
|
||||||
|
Work or Derivative Works thereof in any medium, with or without
|
||||||
|
modifications, and in Source or Object form, provided that You
|
||||||
|
meet the following conditions:
|
||||||
|
|
||||||
|
(a) You must give any other recipients of the Work or
|
||||||
|
Derivative Works a copy of this License; and
|
||||||
|
|
||||||
|
(b) You must cause any modified files to carry prominent notices
|
||||||
|
stating that You changed the files; and
|
||||||
|
|
||||||
|
(c) You must retain, in the Source form of any Derivative Works
|
||||||
|
that You distribute, all copyright, patent, trademark, and
|
||||||
|
attribution notices from the Source form of the Work,
|
||||||
|
excluding those notices that do not pertain to any part of
|
||||||
|
the Derivative Works; and
|
||||||
|
|
||||||
|
(d) If the Work includes a "NOTICE" text file as part of its
|
||||||
|
distribution, then any Derivative Works that You distribute must
|
||||||
|
include a readable copy of the attribution notices contained
|
||||||
|
within such NOTICE file, excluding those notices that do not
|
||||||
|
pertain to any part of the Derivative Works, in at least one
|
||||||
|
of the following places: within a NOTICE text file distributed
|
||||||
|
as part of the Derivative Works; within the Source form or
|
||||||
|
documentation, if provided along with the Derivative Works; or,
|
||||||
|
within a display generated by the Derivative Works, if and
|
||||||
|
wherever such third-party notices normally appear. The contents
|
||||||
|
of the NOTICE file are for informational purposes only and
|
||||||
|
do not modify the License. You may add Your own attribution
|
||||||
|
notices within Derivative Works that You distribute, alongside
|
||||||
|
or as an addendum to the NOTICE text from the Work, provided
|
||||||
|
that such additional attribution notices cannot be construed
|
||||||
|
as modifying the License.
|
||||||
|
|
||||||
|
You may add Your own copyright statement to Your modifications and
|
||||||
|
may provide additional or different license terms and conditions
|
||||||
|
for use, reproduction, or distribution of Your modifications, or
|
||||||
|
for any such Derivative Works as a whole, provided Your use,
|
||||||
|
reproduction, and distribution of the Work otherwise complies with
|
||||||
|
the conditions stated in this License.
|
||||||
|
|
||||||
|
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||||
|
any Contribution intentionally submitted for inclusion in the Work
|
||||||
|
by You to the Licensor shall be under the terms and conditions of
|
||||||
|
this License, without any additional terms or conditions.
|
||||||
|
Notwithstanding the above, nothing herein shall supersede or modify
|
||||||
|
the terms of any separate license agreement you may have executed
|
||||||
|
with Licensor regarding such Contributions.
|
||||||
|
|
||||||
|
6. Trademarks. This License does not grant permission to use the trade
|
||||||
|
names, trademarks, service marks, or product names of the Licensor,
|
||||||
|
except as required for reasonable and customary use in describing the
|
||||||
|
origin of the Work and reproducing the content of the NOTICE file.
|
||||||
|
|
||||||
|
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||||
|
agreed to in writing, Licensor provides the Work (and each
|
||||||
|
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||||
|
implied, including, without limitation, any warranties or conditions
|
||||||
|
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||||
|
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||||
|
appropriateness of using or redistributing the Work and assume any
|
||||||
|
risks associated with Your exercise of permissions under this License.
|
||||||
|
|
||||||
|
8. Limitation of Liability. In no event and under no legal theory,
|
||||||
|
whether in tort (including negligence), contract, or otherwise,
|
||||||
|
unless required by applicable law (such as deliberate and grossly
|
||||||
|
negligent acts) or agreed to in writing, shall any Contributor be
|
||||||
|
liable to You for damages, including any direct, indirect, special,
|
||||||
|
incidental, or consequential damages of any character arising as a
|
||||||
|
result of this License or out of the use or inability to use the
|
||||||
|
Work (including but not limited to damages for loss of goodwill,
|
||||||
|
work stoppage, computer failure or malfunction, or any and all
|
||||||
|
other commercial damages or losses), even if such Contributor
|
||||||
|
has been advised of the possibility of such damages.
|
||||||
|
|
||||||
|
9. Accepting Warranty or Additional Liability. While redistributing
|
||||||
|
the Work or Derivative Works thereof, You may choose to offer,
|
||||||
|
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||||
|
or other liability obligations and/or rights consistent with this
|
||||||
|
License. However, in accepting such obligations, You may act only
|
||||||
|
on Your own behalf and on Your sole responsibility, not on behalf
|
||||||
|
of any other Contributor, and only if You agree to indemnify,
|
||||||
|
defend, and hold each Contributor harmless for any liability
|
||||||
|
incurred by, or claims asserted against, such Contributor by reason
|
||||||
|
of your accepting any such warranty or additional liability.
|
||||||
|
|
||||||
|
END OF TERMS AND CONDITIONS
|
||||||
|
|
||||||
|
APPENDIX: How to apply the Apache License to your work.
|
||||||
|
|
||||||
|
To apply the Apache License to your work, attach the following
|
||||||
|
boilerplate notice, with the fields enclosed by brackets "[]"
|
||||||
|
replaced with your own identifying information. (Don't include
|
||||||
|
the brackets!) The text should be enclosed in the appropriate
|
||||||
|
comment syntax for the file format. We also recommend that a
|
||||||
|
file or class name and description of purpose be included on the
|
||||||
|
same "printed page" as the copyright notice for easier
|
||||||
|
identification within third-party archives.
|
||||||
|
|
||||||
|
Copyright [yyyy] [name of copyright owner]
|
||||||
|
|
||||||
|
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.
|
||||||
|
|
||||||
|
------------------
|
||||||
|
|
||||||
|
Some files carry the following license, noted at the top of each file:
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in
|
||||||
|
all copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
THE SOFTWARE.
|
||||||
|
|
||||||
|
------------------
|
||||||
|
|
||||||
|
Some files carry the "BSD" license, noted at the top of each file:
|
||||||
|
|
||||||
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
modification, are permitted provided that the following conditions are met:
|
||||||
|
|
||||||
|
* Redistributions of source code must retain the above copyright notice,
|
||||||
|
this list of conditions and the following disclaimer.
|
||||||
|
|
||||||
|
* Redistributions in binary form must reproduce the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer in the
|
||||||
|
documentation and/or other materials provided with the distribution.
|
||||||
|
|
||||||
|
* Neither the name of Google Inc. nor the names of its contributors may be
|
||||||
|
used to endorse or promote products derived from this software without
|
||||||
|
specific prior written permission.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||||
|
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||||
|
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||||
|
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||||
|
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||||
|
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||||
|
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
|
POSSIBILITY OF SUCH DAMAGE.
|
||||||
5
README.md
Normal file
5
README.md
Normal file
|
|
@ -0,0 +1,5 @@
|
||||||
|
# gVisor
|
||||||
|
|
||||||
|
This branch is a synthetic branch, containing only Go sources, that is
|
||||||
|
compatible with standard Go tools. See the master branch for authoritative
|
||||||
|
sources and tests.
|
||||||
9
go.mod
Normal file
9
go.mod
Normal file
|
|
@ -0,0 +1,9 @@
|
||||||
|
module github.com/sagernet/gvisor
|
||||||
|
|
||||||
|
go 1.24.1
|
||||||
|
|
||||||
|
require (
|
||||||
|
github.com/google/btree v1.1.2
|
||||||
|
golang.org/x/sys v0.26.0
|
||||||
|
golang.org/x/time v0.7.0
|
||||||
|
)
|
||||||
6
go.sum
Normal file
6
go.sum
Normal file
|
|
@ -0,0 +1,6 @@
|
||||||
|
github.com/google/btree v1.1.2 h1:xf4v41cLI2Z6FxbKm+8Bu+m8ifhj15JuZ9sa0jZCMUU=
|
||||||
|
github.com/google/btree v1.1.2/go.mod h1:qOPhT0dTNdNzV6Z/lhRX0YXUafgPLFUh+gZMl761Gm4=
|
||||||
|
golang.org/x/sys v0.26.0 h1:KHjCJyddX0LoSTb3J+vWpupP9p0oznkqVk/IfjymZbo=
|
||||||
|
golang.org/x/sys v0.26.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||||
|
golang.org/x/time v0.7.0 h1:ntUhktv3OPE6TgYxXWv9vKvUSJyIFJlyohwbkEwPrKQ=
|
||||||
|
golang.org/x/time v0.7.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM=
|
||||||
44
pkg/abi/abi.go
Normal file
44
pkg/abi/abi.go
Normal file
|
|
@ -0,0 +1,44 @@
|
||||||
|
// Copyright 2018 The gVisor 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 abi describes the interface between a kernel and userspace.
|
||||||
|
package abi
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
)
|
||||||
|
|
||||||
|
// OS describes the target operating system for an ABI.
|
||||||
|
//
|
||||||
|
// Note that OS is architecture-independent. The details of the OS ABI will
|
||||||
|
// vary between architectures.
|
||||||
|
type OS int
|
||||||
|
|
||||||
|
const (
|
||||||
|
// Linux is the Linux ABI.
|
||||||
|
Linux OS = iota
|
||||||
|
)
|
||||||
|
|
||||||
|
// String implements fmt.Stringer.
|
||||||
|
func (o OS) String() string {
|
||||||
|
switch o {
|
||||||
|
case Linux:
|
||||||
|
return "linux"
|
||||||
|
default:
|
||||||
|
return fmt.Sprintf("OS(%d)", o)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ABI is an interface that defines OS-specific interactions.
|
||||||
|
type ABI interface{}
|
||||||
21
pkg/abi/abi_linux.go
Normal file
21
pkg/abi/abi_linux.go
Normal file
|
|
@ -0,0 +1,21 @@
|
||||||
|
// Copyright 2018 The gVisor 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.
|
||||||
|
|
||||||
|
//go:build linux
|
||||||
|
// +build linux
|
||||||
|
|
||||||
|
package abi
|
||||||
|
|
||||||
|
// Host specifies the host ABI.
|
||||||
|
const Host = Linux
|
||||||
6
pkg/abi/abi_linux_state_autogen.go
Normal file
6
pkg/abi/abi_linux_state_autogen.go
Normal file
|
|
@ -0,0 +1,6 @@
|
||||||
|
// automatically generated by stateify.
|
||||||
|
|
||||||
|
//go:build linux
|
||||||
|
// +build linux
|
||||||
|
|
||||||
|
package abi
|
||||||
3
pkg/abi/abi_state_autogen.go
Normal file
3
pkg/abi/abi_state_autogen.go
Normal file
|
|
@ -0,0 +1,3 @@
|
||||||
|
// automatically generated by stateify.
|
||||||
|
|
||||||
|
package abi
|
||||||
85
pkg/abi/flag.go
Normal file
85
pkg/abi/flag.go
Normal file
|
|
@ -0,0 +1,85 @@
|
||||||
|
// Copyright 2018 The gVisor 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 abi
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"math"
|
||||||
|
"strconv"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
// A FlagSet is a slice of bit-flags and their name.
|
||||||
|
type FlagSet []struct {
|
||||||
|
Flag uint64
|
||||||
|
Name string
|
||||||
|
}
|
||||||
|
|
||||||
|
// Parse returns a pretty version of val, using the flag names for known flags.
|
||||||
|
// Unknown flags remain numeric.
|
||||||
|
func (s FlagSet) Parse(val uint64) string {
|
||||||
|
var flags []string
|
||||||
|
|
||||||
|
for _, f := range s {
|
||||||
|
if val&f.Flag == f.Flag {
|
||||||
|
flags = append(flags, f.Name)
|
||||||
|
val &^= f.Flag
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if val != 0 {
|
||||||
|
flags = append(flags, "0x"+strconv.FormatUint(val, 16))
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(flags) == 0 {
|
||||||
|
// Prefer 0 to an empty string.
|
||||||
|
return "0x0"
|
||||||
|
}
|
||||||
|
|
||||||
|
return strings.Join(flags, "|")
|
||||||
|
}
|
||||||
|
|
||||||
|
// ValueSet is a map of syscall values to their name. Parse will use the name
|
||||||
|
// or the value if unknown.
|
||||||
|
type ValueSet map[uint64]string
|
||||||
|
|
||||||
|
// Parse returns the name of the value associated with `val`. Unknown values
|
||||||
|
// are converted to hex.
|
||||||
|
func (s ValueSet) Parse(val uint64) string {
|
||||||
|
if v, ok := s[val]; ok {
|
||||||
|
return v
|
||||||
|
}
|
||||||
|
return fmt.Sprintf("%#x", val)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ParseDecimal returns the name of the value associated with `val`. Unknown
|
||||||
|
// values are converted to decimal.
|
||||||
|
func (s ValueSet) ParseDecimal(val uint64) string {
|
||||||
|
if v, ok := s[val]; ok {
|
||||||
|
return v
|
||||||
|
}
|
||||||
|
return fmt.Sprintf("%d", val)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ParseName returns the flag value associated with 'name'. Returns false
|
||||||
|
// if no value is found.
|
||||||
|
func (s ValueSet) ParseName(name string) (uint64, bool) {
|
||||||
|
for k, v := range s {
|
||||||
|
if v == name {
|
||||||
|
return k, true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return math.MaxUint64, false
|
||||||
|
}
|
||||||
127
pkg/abi/gasket/gasket.go
Normal file
127
pkg/abi/gasket/gasket.go
Normal file
|
|
@ -0,0 +1,127 @@
|
||||||
|
// Copyright 2023 The gVisor 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 gasket describes the userspace interface for Gasket devices.
|
||||||
|
package gasket
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
"github.com/sagernet/gvisor/pkg/abi/linux"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Ioctl represents a gasket ioctl command.
|
||||||
|
type Ioctl uint32
|
||||||
|
|
||||||
|
// From https://github.com/tensorflow/tpu/blob/master/tools/driver/include/linux/google/gasket.h
|
||||||
|
var (
|
||||||
|
GASKET_IOCTL_BASE = uint32(0xDC)
|
||||||
|
GASKET_IOCTL_RESET = Ioctl(linux.IOW(GASKET_IOCTL_BASE, 0, SizeOfUnsignedLong))
|
||||||
|
GASKET_IOCTL_SET_EVENTFD = Ioctl(linux.IOW(GASKET_IOCTL_BASE, 1, SizeofGasketInterruptEventFd))
|
||||||
|
GASKET_IOCTL_CLEAR_EVENTFD = Ioctl(linux.IOW(GASKET_IOCTL_BASE, 2, SizeOfUnsignedLong))
|
||||||
|
GASKET_IOCTL_NUMBER_PAGE_TABLES = Ioctl(linux.IOR(GASKET_IOCTL_BASE, 4, SizeOfUnsignedLong))
|
||||||
|
GASKET_IOCTL_PAGE_TABLE_SIZE = Ioctl(linux.IOWR(GASKET_IOCTL_BASE, 5, SizeofGasketPageTableIoctl))
|
||||||
|
GASKET_IOCTL_SIMPLE_PAGE_TABLE_SIZE = Ioctl(linux.IOWR(GASKET_IOCTL_BASE, 6, SizeofGasketPageTableIoctl))
|
||||||
|
GASKET_IOCTL_PARTITION_PAGE_TABLE = Ioctl(linux.IOW(GASKET_IOCTL_BASE, 7, SizeofGasketPageTableIoctl))
|
||||||
|
GASKET_IOCTL_MAP_BUFFER = Ioctl(linux.IOW(GASKET_IOCTL_BASE, 8, SizeofGasketPageTableIoctl))
|
||||||
|
GASKET_IOCTL_UNMAP_BUFFER = Ioctl(linux.IOW(GASKET_IOCTL_BASE, 9, SizeofGasketPageTableIoctl))
|
||||||
|
GASKET_IOCTL_CLEAR_INTERRUPT_COUNTS = Ioctl(linux.IO(GASKET_IOCTL_BASE, 10))
|
||||||
|
GASKET_IOCTL_REGISTER_INTERRUPT = Ioctl(linux.IOW(GASKET_IOCTL_BASE, 11, SizeofGasketInterruptMapping))
|
||||||
|
GASKET_IOCTL_UNREGISTER_INTERRUPT = Ioctl(linux.IOW(GASKET_IOCTL_BASE, 12, SizeOfUnsignedLong))
|
||||||
|
GASKET_IOCTL_MAP_DMA_BUF = Ioctl(linux.IOW(GASKET_IOCTL_BASE, 13, SizeofGasketPageTableDmaBufIoctl))
|
||||||
|
)
|
||||||
|
|
||||||
|
func (i Ioctl) String() string {
|
||||||
|
switch i {
|
||||||
|
case GASKET_IOCTL_RESET:
|
||||||
|
return "GASKET_IOCTL_RESET"
|
||||||
|
case GASKET_IOCTL_SET_EVENTFD:
|
||||||
|
return "GASKET_IOCTL_SET_EVENTFD"
|
||||||
|
case GASKET_IOCTL_CLEAR_EVENTFD:
|
||||||
|
return "GASKET_IOCTL_CLEAR_EVENTFD"
|
||||||
|
case GASKET_IOCTL_NUMBER_PAGE_TABLES:
|
||||||
|
return "GASKET_IOCTL_NUMBER_PAGE_TABLES"
|
||||||
|
case GASKET_IOCTL_PAGE_TABLE_SIZE:
|
||||||
|
return "GASKET_IOCTL_PAGE_TABLE_SIZE"
|
||||||
|
case GASKET_IOCTL_SIMPLE_PAGE_TABLE_SIZE:
|
||||||
|
return "GASKET_IOCTL_SIMPLE_PAGE_TABLE_SIZE"
|
||||||
|
case GASKET_IOCTL_PARTITION_PAGE_TABLE:
|
||||||
|
return "GASKET_IOCTL_PARTITION_PAGE_TABLE"
|
||||||
|
case GASKET_IOCTL_MAP_BUFFER:
|
||||||
|
return "GASKET_IOCTL_MAP_BUFFER"
|
||||||
|
case GASKET_IOCTL_UNMAP_BUFFER:
|
||||||
|
return "GASKET_IOCTL_UNMAP_BUFFER"
|
||||||
|
case GASKET_IOCTL_CLEAR_INTERRUPT_COUNTS:
|
||||||
|
return "GASKET_IOCTL_CLEAR_INTERRUPT_COUNTS"
|
||||||
|
case GASKET_IOCTL_REGISTER_INTERRUPT:
|
||||||
|
return "GASKET_IOCTL_REGISTER_INTERRUPT"
|
||||||
|
case GASKET_IOCTL_UNREGISTER_INTERRUPT:
|
||||||
|
return "GASKET_IOCTL_UNREGISTER_INTERRUPT"
|
||||||
|
case GASKET_IOCTL_MAP_DMA_BUF:
|
||||||
|
return "GASKET_IOCTL_MAP_DMA_BUF"
|
||||||
|
default:
|
||||||
|
return fmt.Sprintf("UNKNOWN GASKET COMMAND %d", uint32(i))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// GasketInterruptEventFd is the common structure for ioctls associating an
|
||||||
|
// eventfd with a device interrupt, when using the Gasket interrupt module.
|
||||||
|
//
|
||||||
|
// +marshal
|
||||||
|
type GasketInterruptEventFd struct {
|
||||||
|
Interrupt uint64
|
||||||
|
EventFD uint64
|
||||||
|
}
|
||||||
|
|
||||||
|
// GasketPageTableIoctl is a common structure for ioctls mapping and unmapping
|
||||||
|
// buffers when using the Gasket page_table module.
|
||||||
|
//
|
||||||
|
// +marshal
|
||||||
|
type GasketPageTableIoctl struct {
|
||||||
|
PageTableIndex uint64
|
||||||
|
Size uint64
|
||||||
|
HostAddress uint64
|
||||||
|
DeviceAddress uint64
|
||||||
|
}
|
||||||
|
|
||||||
|
// GasketInterruptMapping is a structure for ioctls associating an eventfd and
|
||||||
|
// interrupt controlling bar register with a device interrupt, when using the
|
||||||
|
// Gasket interrupt module.
|
||||||
|
//
|
||||||
|
// +marshal
|
||||||
|
type GasketInterruptMapping struct {
|
||||||
|
Interrupt uint64
|
||||||
|
EventFD uint64
|
||||||
|
BarIndex uint64
|
||||||
|
RegOffset uint64
|
||||||
|
}
|
||||||
|
|
||||||
|
// GasketPageTableDmaBufIoctl is a structure for dma_buf mapping ioctl
|
||||||
|
// parameters.
|
||||||
|
//
|
||||||
|
// +marshal
|
||||||
|
type GasketPageTableDmaBufIoctl struct {
|
||||||
|
PageTableIndex uint64
|
||||||
|
DeviceAddress uint64
|
||||||
|
DMABufID int32 `marshal:"unaligned"` // Struct ends mid 64bit word.
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ioctl parameter struct sizes.
|
||||||
|
var (
|
||||||
|
SizeofGasketInterruptEventFd = uint32((*GasketInterruptEventFd)(nil).SizeBytes())
|
||||||
|
SizeofGasketPageTableIoctl = uint32((*GasketPageTableIoctl)(nil).SizeBytes())
|
||||||
|
SizeofGasketInterruptMapping = uint32((*GasketInterruptMapping)(nil).SizeBytes())
|
||||||
|
SizeofGasketPageTableDmaBufIoctl = uint32((*GasketPageTableDmaBufIoctl)(nil).SizeBytes())
|
||||||
|
SizeOfUnsignedLong = uint32(8)
|
||||||
|
)
|
||||||
428
pkg/abi/gasket/gasket_abi_autogen_unsafe.go
Normal file
428
pkg/abi/gasket/gasket_abi_autogen_unsafe.go
Normal file
|
|
@ -0,0 +1,428 @@
|
||||||
|
// Automatically generated marshal implementation. See tools/go_marshal.
|
||||||
|
|
||||||
|
package gasket
|
||||||
|
|
||||||
|
import (
|
||||||
|
"io"
|
||||||
|
"reflect"
|
||||||
|
"runtime"
|
||||||
|
"unsafe"
|
||||||
|
|
||||||
|
"github.com/sagernet/gvisor/pkg/gohacks"
|
||||||
|
"github.com/sagernet/gvisor/pkg/hostarch"
|
||||||
|
"github.com/sagernet/gvisor/pkg/marshal"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Marshallable types used by this file.
|
||||||
|
var (
|
||||||
|
_ marshal.Marshallable = (*GasketInterruptEventFd)(nil)
|
||||||
|
_ marshal.Marshallable = (*GasketInterruptMapping)(nil)
|
||||||
|
_ marshal.Marshallable = (*GasketPageTableDmaBufIoctl)(nil)
|
||||||
|
_ marshal.Marshallable = (*GasketPageTableIoctl)(nil)
|
||||||
|
)
|
||||||
|
|
||||||
|
// SizeBytes implements marshal.Marshallable.SizeBytes.
|
||||||
|
func (g *GasketInterruptEventFd) SizeBytes() int {
|
||||||
|
return 16
|
||||||
|
}
|
||||||
|
|
||||||
|
// MarshalBytes implements marshal.Marshallable.MarshalBytes.
|
||||||
|
func (g *GasketInterruptEventFd) MarshalBytes(dst []byte) []byte {
|
||||||
|
hostarch.ByteOrder.PutUint64(dst[:8], uint64(g.Interrupt))
|
||||||
|
dst = dst[8:]
|
||||||
|
hostarch.ByteOrder.PutUint64(dst[:8], uint64(g.EventFD))
|
||||||
|
dst = dst[8:]
|
||||||
|
return dst
|
||||||
|
}
|
||||||
|
|
||||||
|
// UnmarshalBytes implements marshal.Marshallable.UnmarshalBytes.
|
||||||
|
func (g *GasketInterruptEventFd) UnmarshalBytes(src []byte) []byte {
|
||||||
|
g.Interrupt = uint64(hostarch.ByteOrder.Uint64(src[:8]))
|
||||||
|
src = src[8:]
|
||||||
|
g.EventFD = uint64(hostarch.ByteOrder.Uint64(src[:8]))
|
||||||
|
src = src[8:]
|
||||||
|
return src
|
||||||
|
}
|
||||||
|
|
||||||
|
// Packed implements marshal.Marshallable.Packed.
|
||||||
|
//
|
||||||
|
//go:nosplit
|
||||||
|
func (g *GasketInterruptEventFd) Packed() bool {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
// MarshalUnsafe implements marshal.Marshallable.MarshalUnsafe.
|
||||||
|
func (g *GasketInterruptEventFd) MarshalUnsafe(dst []byte) []byte {
|
||||||
|
size := g.SizeBytes()
|
||||||
|
gohacks.Memmove(unsafe.Pointer(&dst[0]), unsafe.Pointer(g), uintptr(size))
|
||||||
|
return dst[size:]
|
||||||
|
}
|
||||||
|
|
||||||
|
// UnmarshalUnsafe implements marshal.Marshallable.UnmarshalUnsafe.
|
||||||
|
func (g *GasketInterruptEventFd) UnmarshalUnsafe(src []byte) []byte {
|
||||||
|
size := g.SizeBytes()
|
||||||
|
gohacks.Memmove(unsafe.Pointer(g), unsafe.Pointer(&src[0]), uintptr(size))
|
||||||
|
return src[size:]
|
||||||
|
}
|
||||||
|
|
||||||
|
// CopyOutN implements marshal.Marshallable.CopyOutN.
|
||||||
|
func (g *GasketInterruptEventFd) CopyOutN(cc marshal.CopyContext, addr hostarch.Addr, limit int) (int, error) {
|
||||||
|
// Construct a slice backed by dst's underlying memory.
|
||||||
|
var buf []byte
|
||||||
|
hdr := (*reflect.SliceHeader)(unsafe.Pointer(&buf))
|
||||||
|
hdr.Data = uintptr(gohacks.Noescape(unsafe.Pointer(g)))
|
||||||
|
hdr.Len = g.SizeBytes()
|
||||||
|
hdr.Cap = g.SizeBytes()
|
||||||
|
|
||||||
|
length, err := cc.CopyOutBytes(addr, buf[:limit]) // escapes: okay.
|
||||||
|
// Since we bypassed the compiler's escape analysis, indicate that g
|
||||||
|
// must live until the use above.
|
||||||
|
runtime.KeepAlive(g) // escapes: replaced by intrinsic.
|
||||||
|
return length, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// CopyOut implements marshal.Marshallable.CopyOut.
|
||||||
|
func (g *GasketInterruptEventFd) CopyOut(cc marshal.CopyContext, addr hostarch.Addr) (int, error) {
|
||||||
|
return g.CopyOutN(cc, addr, g.SizeBytes())
|
||||||
|
}
|
||||||
|
|
||||||
|
// CopyInN implements marshal.Marshallable.CopyInN.
|
||||||
|
func (g *GasketInterruptEventFd) CopyInN(cc marshal.CopyContext, addr hostarch.Addr, limit int) (int, error) {
|
||||||
|
// Construct a slice backed by dst's underlying memory.
|
||||||
|
var buf []byte
|
||||||
|
hdr := (*reflect.SliceHeader)(unsafe.Pointer(&buf))
|
||||||
|
hdr.Data = uintptr(gohacks.Noescape(unsafe.Pointer(g)))
|
||||||
|
hdr.Len = g.SizeBytes()
|
||||||
|
hdr.Cap = g.SizeBytes()
|
||||||
|
|
||||||
|
length, err := cc.CopyInBytes(addr, buf[:limit]) // escapes: okay.
|
||||||
|
// Since we bypassed the compiler's escape analysis, indicate that g
|
||||||
|
// must live until the use above.
|
||||||
|
runtime.KeepAlive(g) // escapes: replaced by intrinsic.
|
||||||
|
return length, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// CopyIn implements marshal.Marshallable.CopyIn.
|
||||||
|
func (g *GasketInterruptEventFd) CopyIn(cc marshal.CopyContext, addr hostarch.Addr) (int, error) {
|
||||||
|
return g.CopyInN(cc, addr, g.SizeBytes())
|
||||||
|
}
|
||||||
|
|
||||||
|
// WriteTo implements io.WriterTo.WriteTo.
|
||||||
|
func (g *GasketInterruptEventFd) WriteTo(writer io.Writer) (int64, error) {
|
||||||
|
// Construct a slice backed by dst's underlying memory.
|
||||||
|
var buf []byte
|
||||||
|
hdr := (*reflect.SliceHeader)(unsafe.Pointer(&buf))
|
||||||
|
hdr.Data = uintptr(gohacks.Noescape(unsafe.Pointer(g)))
|
||||||
|
hdr.Len = g.SizeBytes()
|
||||||
|
hdr.Cap = g.SizeBytes()
|
||||||
|
|
||||||
|
length, err := writer.Write(buf)
|
||||||
|
// Since we bypassed the compiler's escape analysis, indicate that g
|
||||||
|
// must live until the use above.
|
||||||
|
runtime.KeepAlive(g) // escapes: replaced by intrinsic.
|
||||||
|
return int64(length), err
|
||||||
|
}
|
||||||
|
|
||||||
|
// SizeBytes implements marshal.Marshallable.SizeBytes.
|
||||||
|
func (g *GasketInterruptMapping) SizeBytes() int {
|
||||||
|
return 32
|
||||||
|
}
|
||||||
|
|
||||||
|
// MarshalBytes implements marshal.Marshallable.MarshalBytes.
|
||||||
|
func (g *GasketInterruptMapping) MarshalBytes(dst []byte) []byte {
|
||||||
|
hostarch.ByteOrder.PutUint64(dst[:8], uint64(g.Interrupt))
|
||||||
|
dst = dst[8:]
|
||||||
|
hostarch.ByteOrder.PutUint64(dst[:8], uint64(g.EventFD))
|
||||||
|
dst = dst[8:]
|
||||||
|
hostarch.ByteOrder.PutUint64(dst[:8], uint64(g.BarIndex))
|
||||||
|
dst = dst[8:]
|
||||||
|
hostarch.ByteOrder.PutUint64(dst[:8], uint64(g.RegOffset))
|
||||||
|
dst = dst[8:]
|
||||||
|
return dst
|
||||||
|
}
|
||||||
|
|
||||||
|
// UnmarshalBytes implements marshal.Marshallable.UnmarshalBytes.
|
||||||
|
func (g *GasketInterruptMapping) UnmarshalBytes(src []byte) []byte {
|
||||||
|
g.Interrupt = uint64(hostarch.ByteOrder.Uint64(src[:8]))
|
||||||
|
src = src[8:]
|
||||||
|
g.EventFD = uint64(hostarch.ByteOrder.Uint64(src[:8]))
|
||||||
|
src = src[8:]
|
||||||
|
g.BarIndex = uint64(hostarch.ByteOrder.Uint64(src[:8]))
|
||||||
|
src = src[8:]
|
||||||
|
g.RegOffset = uint64(hostarch.ByteOrder.Uint64(src[:8]))
|
||||||
|
src = src[8:]
|
||||||
|
return src
|
||||||
|
}
|
||||||
|
|
||||||
|
// Packed implements marshal.Marshallable.Packed.
|
||||||
|
//
|
||||||
|
//go:nosplit
|
||||||
|
func (g *GasketInterruptMapping) Packed() bool {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
// MarshalUnsafe implements marshal.Marshallable.MarshalUnsafe.
|
||||||
|
func (g *GasketInterruptMapping) MarshalUnsafe(dst []byte) []byte {
|
||||||
|
size := g.SizeBytes()
|
||||||
|
gohacks.Memmove(unsafe.Pointer(&dst[0]), unsafe.Pointer(g), uintptr(size))
|
||||||
|
return dst[size:]
|
||||||
|
}
|
||||||
|
|
||||||
|
// UnmarshalUnsafe implements marshal.Marshallable.UnmarshalUnsafe.
|
||||||
|
func (g *GasketInterruptMapping) UnmarshalUnsafe(src []byte) []byte {
|
||||||
|
size := g.SizeBytes()
|
||||||
|
gohacks.Memmove(unsafe.Pointer(g), unsafe.Pointer(&src[0]), uintptr(size))
|
||||||
|
return src[size:]
|
||||||
|
}
|
||||||
|
|
||||||
|
// CopyOutN implements marshal.Marshallable.CopyOutN.
|
||||||
|
func (g *GasketInterruptMapping) CopyOutN(cc marshal.CopyContext, addr hostarch.Addr, limit int) (int, error) {
|
||||||
|
// Construct a slice backed by dst's underlying memory.
|
||||||
|
var buf []byte
|
||||||
|
hdr := (*reflect.SliceHeader)(unsafe.Pointer(&buf))
|
||||||
|
hdr.Data = uintptr(gohacks.Noescape(unsafe.Pointer(g)))
|
||||||
|
hdr.Len = g.SizeBytes()
|
||||||
|
hdr.Cap = g.SizeBytes()
|
||||||
|
|
||||||
|
length, err := cc.CopyOutBytes(addr, buf[:limit]) // escapes: okay.
|
||||||
|
// Since we bypassed the compiler's escape analysis, indicate that g
|
||||||
|
// must live until the use above.
|
||||||
|
runtime.KeepAlive(g) // escapes: replaced by intrinsic.
|
||||||
|
return length, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// CopyOut implements marshal.Marshallable.CopyOut.
|
||||||
|
func (g *GasketInterruptMapping) CopyOut(cc marshal.CopyContext, addr hostarch.Addr) (int, error) {
|
||||||
|
return g.CopyOutN(cc, addr, g.SizeBytes())
|
||||||
|
}
|
||||||
|
|
||||||
|
// CopyInN implements marshal.Marshallable.CopyInN.
|
||||||
|
func (g *GasketInterruptMapping) CopyInN(cc marshal.CopyContext, addr hostarch.Addr, limit int) (int, error) {
|
||||||
|
// Construct a slice backed by dst's underlying memory.
|
||||||
|
var buf []byte
|
||||||
|
hdr := (*reflect.SliceHeader)(unsafe.Pointer(&buf))
|
||||||
|
hdr.Data = uintptr(gohacks.Noescape(unsafe.Pointer(g)))
|
||||||
|
hdr.Len = g.SizeBytes()
|
||||||
|
hdr.Cap = g.SizeBytes()
|
||||||
|
|
||||||
|
length, err := cc.CopyInBytes(addr, buf[:limit]) // escapes: okay.
|
||||||
|
// Since we bypassed the compiler's escape analysis, indicate that g
|
||||||
|
// must live until the use above.
|
||||||
|
runtime.KeepAlive(g) // escapes: replaced by intrinsic.
|
||||||
|
return length, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// CopyIn implements marshal.Marshallable.CopyIn.
|
||||||
|
func (g *GasketInterruptMapping) CopyIn(cc marshal.CopyContext, addr hostarch.Addr) (int, error) {
|
||||||
|
return g.CopyInN(cc, addr, g.SizeBytes())
|
||||||
|
}
|
||||||
|
|
||||||
|
// WriteTo implements io.WriterTo.WriteTo.
|
||||||
|
func (g *GasketInterruptMapping) WriteTo(writer io.Writer) (int64, error) {
|
||||||
|
// Construct a slice backed by dst's underlying memory.
|
||||||
|
var buf []byte
|
||||||
|
hdr := (*reflect.SliceHeader)(unsafe.Pointer(&buf))
|
||||||
|
hdr.Data = uintptr(gohacks.Noescape(unsafe.Pointer(g)))
|
||||||
|
hdr.Len = g.SizeBytes()
|
||||||
|
hdr.Cap = g.SizeBytes()
|
||||||
|
|
||||||
|
length, err := writer.Write(buf)
|
||||||
|
// Since we bypassed the compiler's escape analysis, indicate that g
|
||||||
|
// must live until the use above.
|
||||||
|
runtime.KeepAlive(g) // escapes: replaced by intrinsic.
|
||||||
|
return int64(length), err
|
||||||
|
}
|
||||||
|
|
||||||
|
// SizeBytes implements marshal.Marshallable.SizeBytes.
|
||||||
|
func (g *GasketPageTableDmaBufIoctl) SizeBytes() int {
|
||||||
|
return 20
|
||||||
|
}
|
||||||
|
|
||||||
|
// MarshalBytes implements marshal.Marshallable.MarshalBytes.
|
||||||
|
func (g *GasketPageTableDmaBufIoctl) MarshalBytes(dst []byte) []byte {
|
||||||
|
hostarch.ByteOrder.PutUint64(dst[:8], uint64(g.PageTableIndex))
|
||||||
|
dst = dst[8:]
|
||||||
|
hostarch.ByteOrder.PutUint64(dst[:8], uint64(g.DeviceAddress))
|
||||||
|
dst = dst[8:]
|
||||||
|
hostarch.ByteOrder.PutUint32(dst[:4], uint32(g.DMABufID))
|
||||||
|
dst = dst[4:]
|
||||||
|
return dst
|
||||||
|
}
|
||||||
|
|
||||||
|
// UnmarshalBytes implements marshal.Marshallable.UnmarshalBytes.
|
||||||
|
func (g *GasketPageTableDmaBufIoctl) UnmarshalBytes(src []byte) []byte {
|
||||||
|
g.PageTableIndex = uint64(hostarch.ByteOrder.Uint64(src[:8]))
|
||||||
|
src = src[8:]
|
||||||
|
g.DeviceAddress = uint64(hostarch.ByteOrder.Uint64(src[:8]))
|
||||||
|
src = src[8:]
|
||||||
|
g.DMABufID = int32(hostarch.ByteOrder.Uint32(src[:4]))
|
||||||
|
src = src[4:]
|
||||||
|
return src
|
||||||
|
}
|
||||||
|
|
||||||
|
// Packed implements marshal.Marshallable.Packed.
|
||||||
|
//
|
||||||
|
//go:nosplit
|
||||||
|
func (g *GasketPageTableDmaBufIoctl) Packed() bool {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
// MarshalUnsafe implements marshal.Marshallable.MarshalUnsafe.
|
||||||
|
func (g *GasketPageTableDmaBufIoctl) MarshalUnsafe(dst []byte) []byte {
|
||||||
|
// Type GasketPageTableDmaBufIoctl doesn't have a packed layout in memory, fallback to MarshalBytes.
|
||||||
|
return g.MarshalBytes(dst)
|
||||||
|
}
|
||||||
|
|
||||||
|
// UnmarshalUnsafe implements marshal.Marshallable.UnmarshalUnsafe.
|
||||||
|
func (g *GasketPageTableDmaBufIoctl) UnmarshalUnsafe(src []byte) []byte {
|
||||||
|
// Type GasketPageTableDmaBufIoctl doesn't have a packed layout in memory, fallback to UnmarshalBytes.
|
||||||
|
return g.UnmarshalBytes(src)
|
||||||
|
}
|
||||||
|
|
||||||
|
// CopyOutN implements marshal.Marshallable.CopyOutN.
|
||||||
|
func (g *GasketPageTableDmaBufIoctl) CopyOutN(cc marshal.CopyContext, addr hostarch.Addr, limit int) (int, error) {
|
||||||
|
// Type GasketPageTableDmaBufIoctl doesn't have a packed layout in memory, fall back to MarshalBytes.
|
||||||
|
buf := cc.CopyScratchBuffer(g.SizeBytes()) // escapes: okay.
|
||||||
|
g.MarshalBytes(buf) // escapes: fallback.
|
||||||
|
return cc.CopyOutBytes(addr, buf[:limit]) // escapes: okay.
|
||||||
|
}
|
||||||
|
|
||||||
|
// CopyOut implements marshal.Marshallable.CopyOut.
|
||||||
|
func (g *GasketPageTableDmaBufIoctl) CopyOut(cc marshal.CopyContext, addr hostarch.Addr) (int, error) {
|
||||||
|
return g.CopyOutN(cc, addr, g.SizeBytes())
|
||||||
|
}
|
||||||
|
|
||||||
|
// CopyInN implements marshal.Marshallable.CopyInN.
|
||||||
|
func (g *GasketPageTableDmaBufIoctl) CopyInN(cc marshal.CopyContext, addr hostarch.Addr, limit int) (int, error) {
|
||||||
|
// Type GasketPageTableDmaBufIoctl doesn't have a packed layout in memory, fall back to UnmarshalBytes.
|
||||||
|
buf := cc.CopyScratchBuffer(g.SizeBytes()) // escapes: okay.
|
||||||
|
length, err := cc.CopyInBytes(addr, buf[:limit]) // escapes: okay.
|
||||||
|
// Unmarshal unconditionally. If we had a short copy-in, this results in a
|
||||||
|
// partially unmarshalled struct.
|
||||||
|
g.UnmarshalBytes(buf) // escapes: fallback.
|
||||||
|
return length, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// CopyIn implements marshal.Marshallable.CopyIn.
|
||||||
|
func (g *GasketPageTableDmaBufIoctl) CopyIn(cc marshal.CopyContext, addr hostarch.Addr) (int, error) {
|
||||||
|
return g.CopyInN(cc, addr, g.SizeBytes())
|
||||||
|
}
|
||||||
|
|
||||||
|
// WriteTo implements io.WriterTo.WriteTo.
|
||||||
|
func (g *GasketPageTableDmaBufIoctl) WriteTo(writer io.Writer) (int64, error) {
|
||||||
|
// Type GasketPageTableDmaBufIoctl doesn't have a packed layout in memory, fall back to MarshalBytes.
|
||||||
|
buf := make([]byte, g.SizeBytes())
|
||||||
|
g.MarshalBytes(buf)
|
||||||
|
length, err := writer.Write(buf)
|
||||||
|
return int64(length), err
|
||||||
|
}
|
||||||
|
|
||||||
|
// SizeBytes implements marshal.Marshallable.SizeBytes.
|
||||||
|
func (g *GasketPageTableIoctl) SizeBytes() int {
|
||||||
|
return 32
|
||||||
|
}
|
||||||
|
|
||||||
|
// MarshalBytes implements marshal.Marshallable.MarshalBytes.
|
||||||
|
func (g *GasketPageTableIoctl) MarshalBytes(dst []byte) []byte {
|
||||||
|
hostarch.ByteOrder.PutUint64(dst[:8], uint64(g.PageTableIndex))
|
||||||
|
dst = dst[8:]
|
||||||
|
hostarch.ByteOrder.PutUint64(dst[:8], uint64(g.Size))
|
||||||
|
dst = dst[8:]
|
||||||
|
hostarch.ByteOrder.PutUint64(dst[:8], uint64(g.HostAddress))
|
||||||
|
dst = dst[8:]
|
||||||
|
hostarch.ByteOrder.PutUint64(dst[:8], uint64(g.DeviceAddress))
|
||||||
|
dst = dst[8:]
|
||||||
|
return dst
|
||||||
|
}
|
||||||
|
|
||||||
|
// UnmarshalBytes implements marshal.Marshallable.UnmarshalBytes.
|
||||||
|
func (g *GasketPageTableIoctl) UnmarshalBytes(src []byte) []byte {
|
||||||
|
g.PageTableIndex = uint64(hostarch.ByteOrder.Uint64(src[:8]))
|
||||||
|
src = src[8:]
|
||||||
|
g.Size = uint64(hostarch.ByteOrder.Uint64(src[:8]))
|
||||||
|
src = src[8:]
|
||||||
|
g.HostAddress = uint64(hostarch.ByteOrder.Uint64(src[:8]))
|
||||||
|
src = src[8:]
|
||||||
|
g.DeviceAddress = uint64(hostarch.ByteOrder.Uint64(src[:8]))
|
||||||
|
src = src[8:]
|
||||||
|
return src
|
||||||
|
}
|
||||||
|
|
||||||
|
// Packed implements marshal.Marshallable.Packed.
|
||||||
|
//
|
||||||
|
//go:nosplit
|
||||||
|
func (g *GasketPageTableIoctl) Packed() bool {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
// MarshalUnsafe implements marshal.Marshallable.MarshalUnsafe.
|
||||||
|
func (g *GasketPageTableIoctl) MarshalUnsafe(dst []byte) []byte {
|
||||||
|
size := g.SizeBytes()
|
||||||
|
gohacks.Memmove(unsafe.Pointer(&dst[0]), unsafe.Pointer(g), uintptr(size))
|
||||||
|
return dst[size:]
|
||||||
|
}
|
||||||
|
|
||||||
|
// UnmarshalUnsafe implements marshal.Marshallable.UnmarshalUnsafe.
|
||||||
|
func (g *GasketPageTableIoctl) UnmarshalUnsafe(src []byte) []byte {
|
||||||
|
size := g.SizeBytes()
|
||||||
|
gohacks.Memmove(unsafe.Pointer(g), unsafe.Pointer(&src[0]), uintptr(size))
|
||||||
|
return src[size:]
|
||||||
|
}
|
||||||
|
|
||||||
|
// CopyOutN implements marshal.Marshallable.CopyOutN.
|
||||||
|
func (g *GasketPageTableIoctl) CopyOutN(cc marshal.CopyContext, addr hostarch.Addr, limit int) (int, error) {
|
||||||
|
// Construct a slice backed by dst's underlying memory.
|
||||||
|
var buf []byte
|
||||||
|
hdr := (*reflect.SliceHeader)(unsafe.Pointer(&buf))
|
||||||
|
hdr.Data = uintptr(gohacks.Noescape(unsafe.Pointer(g)))
|
||||||
|
hdr.Len = g.SizeBytes()
|
||||||
|
hdr.Cap = g.SizeBytes()
|
||||||
|
|
||||||
|
length, err := cc.CopyOutBytes(addr, buf[:limit]) // escapes: okay.
|
||||||
|
// Since we bypassed the compiler's escape analysis, indicate that g
|
||||||
|
// must live until the use above.
|
||||||
|
runtime.KeepAlive(g) // escapes: replaced by intrinsic.
|
||||||
|
return length, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// CopyOut implements marshal.Marshallable.CopyOut.
|
||||||
|
func (g *GasketPageTableIoctl) CopyOut(cc marshal.CopyContext, addr hostarch.Addr) (int, error) {
|
||||||
|
return g.CopyOutN(cc, addr, g.SizeBytes())
|
||||||
|
}
|
||||||
|
|
||||||
|
// CopyInN implements marshal.Marshallable.CopyInN.
|
||||||
|
func (g *GasketPageTableIoctl) CopyInN(cc marshal.CopyContext, addr hostarch.Addr, limit int) (int, error) {
|
||||||
|
// Construct a slice backed by dst's underlying memory.
|
||||||
|
var buf []byte
|
||||||
|
hdr := (*reflect.SliceHeader)(unsafe.Pointer(&buf))
|
||||||
|
hdr.Data = uintptr(gohacks.Noescape(unsafe.Pointer(g)))
|
||||||
|
hdr.Len = g.SizeBytes()
|
||||||
|
hdr.Cap = g.SizeBytes()
|
||||||
|
|
||||||
|
length, err := cc.CopyInBytes(addr, buf[:limit]) // escapes: okay.
|
||||||
|
// Since we bypassed the compiler's escape analysis, indicate that g
|
||||||
|
// must live until the use above.
|
||||||
|
runtime.KeepAlive(g) // escapes: replaced by intrinsic.
|
||||||
|
return length, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// CopyIn implements marshal.Marshallable.CopyIn.
|
||||||
|
func (g *GasketPageTableIoctl) CopyIn(cc marshal.CopyContext, addr hostarch.Addr) (int, error) {
|
||||||
|
return g.CopyInN(cc, addr, g.SizeBytes())
|
||||||
|
}
|
||||||
|
|
||||||
|
// WriteTo implements io.WriterTo.WriteTo.
|
||||||
|
func (g *GasketPageTableIoctl) WriteTo(writer io.Writer) (int64, error) {
|
||||||
|
// Construct a slice backed by dst's underlying memory.
|
||||||
|
var buf []byte
|
||||||
|
hdr := (*reflect.SliceHeader)(unsafe.Pointer(&buf))
|
||||||
|
hdr.Data = uintptr(gohacks.Noescape(unsafe.Pointer(g)))
|
||||||
|
hdr.Len = g.SizeBytes()
|
||||||
|
hdr.Cap = g.SizeBytes()
|
||||||
|
|
||||||
|
length, err := writer.Write(buf)
|
||||||
|
// Since we bypassed the compiler's escape analysis, indicate that g
|
||||||
|
// must live until the use above.
|
||||||
|
runtime.KeepAlive(g) // escapes: replaced by intrinsic.
|
||||||
|
return int64(length), err
|
||||||
|
}
|
||||||
3
pkg/abi/gasket/gasket_state_autogen.go
Normal file
3
pkg/abi/gasket/gasket_state_autogen.go
Normal file
|
|
@ -0,0 +1,3 @@
|
||||||
|
// automatically generated by stateify.
|
||||||
|
|
||||||
|
package gasket
|
||||||
96
pkg/abi/linux/aio.go
Normal file
96
pkg/abi/linux/aio.go
Normal file
|
|
@ -0,0 +1,96 @@
|
||||||
|
// Copyright 2018 The gVisor 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 linux
|
||||||
|
|
||||||
|
import "encoding/binary"
|
||||||
|
|
||||||
|
// AIORing is struct aio_ring, from fs/aio.c, without the trailing
|
||||||
|
// variable-length array.
|
||||||
|
type AIORing struct {
|
||||||
|
ID uint32
|
||||||
|
Nr uint32
|
||||||
|
Head uint32
|
||||||
|
Tail uint32
|
||||||
|
Magic uint32
|
||||||
|
CompatFeatures uint32
|
||||||
|
IncompatFeatures uint32
|
||||||
|
HeaderLength uint32
|
||||||
|
}
|
||||||
|
|
||||||
|
// AIORingSize is sizeof(struct aio_ring).
|
||||||
|
const AIORingSize = 32
|
||||||
|
|
||||||
|
// AIO_RING_MAGIC is fs/aio.c:AIO_RING_MAGIC, the expected value of
|
||||||
|
// AIORing.Magic.
|
||||||
|
const AIO_RING_MAGIC = 0xa10a10a1
|
||||||
|
|
||||||
|
// I/O commands.
|
||||||
|
const (
|
||||||
|
IOCB_CMD_PREAD = 0
|
||||||
|
IOCB_CMD_PWRITE = 1
|
||||||
|
IOCB_CMD_FSYNC = 2
|
||||||
|
IOCB_CMD_FDSYNC = 3
|
||||||
|
// 4 was the experimental IOCB_CMD_PREADX.
|
||||||
|
IOCB_CMD_POLL = 5
|
||||||
|
IOCB_CMD_NOOP = 6
|
||||||
|
IOCB_CMD_PREADV = 7
|
||||||
|
IOCB_CMD_PWRITEV = 8
|
||||||
|
)
|
||||||
|
|
||||||
|
// I/O flags.
|
||||||
|
const (
|
||||||
|
IOCB_FLAG_RESFD = 1
|
||||||
|
IOCB_FLAG_IOPRIO = 2
|
||||||
|
)
|
||||||
|
|
||||||
|
// IOCallback describes an I/O request.
|
||||||
|
//
|
||||||
|
// The priority field is currently ignored in the implementation below. Also
|
||||||
|
// note that the IOCB_FLAG_RESFD feature is not supported.
|
||||||
|
//
|
||||||
|
// +marshal
|
||||||
|
type IOCallback struct {
|
||||||
|
Data uint64
|
||||||
|
Key uint32
|
||||||
|
_ uint32
|
||||||
|
|
||||||
|
OpCode uint16
|
||||||
|
ReqPrio int16
|
||||||
|
FD int32
|
||||||
|
|
||||||
|
Buf uint64
|
||||||
|
Bytes uint64
|
||||||
|
Offset int64
|
||||||
|
|
||||||
|
Reserved2 uint64
|
||||||
|
Flags uint32
|
||||||
|
|
||||||
|
// eventfd to signal if IOCB_FLAG_RESFD is set in flags.
|
||||||
|
ResFD int32
|
||||||
|
}
|
||||||
|
|
||||||
|
// IOEvent describes an I/O result.
|
||||||
|
//
|
||||||
|
// +marshal
|
||||||
|
// +stateify savable
|
||||||
|
type IOEvent struct {
|
||||||
|
Data uint64
|
||||||
|
Obj uint64
|
||||||
|
Result int64
|
||||||
|
Result2 int64
|
||||||
|
}
|
||||||
|
|
||||||
|
// IOEventSize is the size of an ioEvent encoded.
|
||||||
|
var IOEventSize = binary.Size(IOEvent{})
|
||||||
24
pkg/abi/linux/arch_amd64.go
Normal file
24
pkg/abi/linux/arch_amd64.go
Normal file
|
|
@ -0,0 +1,24 @@
|
||||||
|
// Copyright 2020 The gVisor 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.
|
||||||
|
|
||||||
|
//go:build amd64
|
||||||
|
// +build amd64
|
||||||
|
|
||||||
|
package linux
|
||||||
|
|
||||||
|
// Start and end addresses of the vsyscall page.
|
||||||
|
const (
|
||||||
|
VSyscallStartAddr uint64 = 0xffffffffff600000
|
||||||
|
VSyscallEndAddr uint64 = 0xffffffffff601000
|
||||||
|
)
|
||||||
23
pkg/abi/linux/audit.go
Normal file
23
pkg/abi/linux/audit.go
Normal file
|
|
@ -0,0 +1,23 @@
|
||||||
|
// Copyright 2018 The gVisor 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 linux
|
||||||
|
|
||||||
|
// Audit numbers identify different system call APIs, from <uapi/linux/audit.h>
|
||||||
|
const (
|
||||||
|
// AUDIT_ARCH_X86_64 identifies AMD64.
|
||||||
|
AUDIT_ARCH_X86_64 = 0xc000003e
|
||||||
|
// AUDIT_ARCH_AARCH64 identifies ARM64.
|
||||||
|
AUDIT_ARCH_AARCH64 = 0xc00000b7
|
||||||
|
)
|
||||||
35
pkg/abi/linux/bpf.go
Normal file
35
pkg/abi/linux/bpf.go
Normal file
|
|
@ -0,0 +1,35 @@
|
||||||
|
// Copyright 2018 The gVisor 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 linux
|
||||||
|
|
||||||
|
// BPFInstruction is a raw BPF virtual machine instruction.
|
||||||
|
//
|
||||||
|
// +marshal slice:BPFInstructionSlice
|
||||||
|
// +stateify savable
|
||||||
|
type BPFInstruction struct {
|
||||||
|
// OpCode is the operation to execute.
|
||||||
|
OpCode uint16
|
||||||
|
|
||||||
|
// JumpIfTrue is the number of instructions to skip if OpCode is a
|
||||||
|
// conditional instruction and the condition is true.
|
||||||
|
JumpIfTrue uint8
|
||||||
|
|
||||||
|
// JumpIfFalse is the number of instructions to skip if OpCode is a
|
||||||
|
// conditional instruction and the condition is false.
|
||||||
|
JumpIfFalse uint8
|
||||||
|
|
||||||
|
// K is a constant parameter. The meaning depends on the value of OpCode.
|
||||||
|
K uint32
|
||||||
|
}
|
||||||
337
pkg/abi/linux/capability.go
Normal file
337
pkg/abi/linux/capability.go
Normal file
|
|
@ -0,0 +1,337 @@
|
||||||
|
// Copyright 2018 The gVisor 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 linux
|
||||||
|
|
||||||
|
import (
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
// A Capability represents the ability to perform a privileged operation.
|
||||||
|
type Capability int
|
||||||
|
|
||||||
|
// Capabilities defined by Linux. Taken from the kernel's
|
||||||
|
// include/uapi/linux/capability.h. See capabilities(7) or that file for more
|
||||||
|
// detailed capability descriptions.
|
||||||
|
const (
|
||||||
|
CAP_CHOWN = Capability(0)
|
||||||
|
CAP_DAC_OVERRIDE = Capability(1)
|
||||||
|
CAP_DAC_READ_SEARCH = Capability(2)
|
||||||
|
CAP_FOWNER = Capability(3)
|
||||||
|
CAP_FSETID = Capability(4)
|
||||||
|
CAP_KILL = Capability(5)
|
||||||
|
CAP_SETGID = Capability(6)
|
||||||
|
CAP_SETUID = Capability(7)
|
||||||
|
CAP_SETPCAP = Capability(8)
|
||||||
|
CAP_LINUX_IMMUTABLE = Capability(9)
|
||||||
|
CAP_NET_BIND_SERVICE = Capability(10)
|
||||||
|
CAP_NET_BROADCAST = Capability(11)
|
||||||
|
CAP_NET_ADMIN = Capability(12)
|
||||||
|
CAP_NET_RAW = Capability(13)
|
||||||
|
CAP_IPC_LOCK = Capability(14)
|
||||||
|
CAP_IPC_OWNER = Capability(15)
|
||||||
|
CAP_SYS_MODULE = Capability(16)
|
||||||
|
CAP_SYS_RAWIO = Capability(17)
|
||||||
|
CAP_SYS_CHROOT = Capability(18)
|
||||||
|
CAP_SYS_PTRACE = Capability(19)
|
||||||
|
CAP_SYS_PACCT = Capability(20)
|
||||||
|
CAP_SYS_ADMIN = Capability(21)
|
||||||
|
CAP_SYS_BOOT = Capability(22)
|
||||||
|
CAP_SYS_NICE = Capability(23)
|
||||||
|
CAP_SYS_RESOURCE = Capability(24)
|
||||||
|
CAP_SYS_TIME = Capability(25)
|
||||||
|
CAP_SYS_TTY_CONFIG = Capability(26)
|
||||||
|
CAP_MKNOD = Capability(27)
|
||||||
|
CAP_LEASE = Capability(28)
|
||||||
|
CAP_AUDIT_WRITE = Capability(29)
|
||||||
|
CAP_AUDIT_CONTROL = Capability(30)
|
||||||
|
CAP_SETFCAP = Capability(31)
|
||||||
|
CAP_MAC_OVERRIDE = Capability(32)
|
||||||
|
CAP_MAC_ADMIN = Capability(33)
|
||||||
|
CAP_SYSLOG = Capability(34)
|
||||||
|
CAP_WAKE_ALARM = Capability(35)
|
||||||
|
CAP_BLOCK_SUSPEND = Capability(36)
|
||||||
|
CAP_AUDIT_READ = Capability(37)
|
||||||
|
CAP_PERFMON = Capability(38)
|
||||||
|
CAP_BPF = Capability(39)
|
||||||
|
CAP_CHECKPOINT_RESTORE = Capability(40)
|
||||||
|
|
||||||
|
// CAP_LAST_CAP is the highest-numbered capability.
|
||||||
|
// Search for "CAP_LAST_CAP" to find other places that need to change.
|
||||||
|
CAP_LAST_CAP = CAP_CHECKPOINT_RESTORE
|
||||||
|
)
|
||||||
|
|
||||||
|
// Ok returns true if cp is a supported capability.
|
||||||
|
func (cp Capability) Ok() bool {
|
||||||
|
return cp >= 0 && cp <= CAP_LAST_CAP
|
||||||
|
}
|
||||||
|
|
||||||
|
// String returns the capability name.
|
||||||
|
func (cp Capability) String() string {
|
||||||
|
switch cp {
|
||||||
|
case CAP_CHOWN:
|
||||||
|
return "CAP_CHOWN"
|
||||||
|
case CAP_DAC_OVERRIDE:
|
||||||
|
return "CAP_DAC_OVERRIDE"
|
||||||
|
case CAP_DAC_READ_SEARCH:
|
||||||
|
return "CAP_DAC_READ_SEARCH"
|
||||||
|
case CAP_FOWNER:
|
||||||
|
return "CAP_FOWNER"
|
||||||
|
case CAP_FSETID:
|
||||||
|
return "CAP_FSETID"
|
||||||
|
case CAP_KILL:
|
||||||
|
return "CAP_KILL"
|
||||||
|
case CAP_SETGID:
|
||||||
|
return "CAP_SETGID"
|
||||||
|
case CAP_SETUID:
|
||||||
|
return "CAP_SETUID"
|
||||||
|
case CAP_SETPCAP:
|
||||||
|
return "CAP_SETPCAP"
|
||||||
|
case CAP_LINUX_IMMUTABLE:
|
||||||
|
return "CAP_LINUX_IMMUTABLE"
|
||||||
|
case CAP_NET_BIND_SERVICE:
|
||||||
|
return "CAP_NET_BIND_SERVICE"
|
||||||
|
case CAP_NET_BROADCAST:
|
||||||
|
return "CAP_NET_BROADCAST"
|
||||||
|
case CAP_NET_ADMIN:
|
||||||
|
return "CAP_NET_ADMIN"
|
||||||
|
case CAP_NET_RAW:
|
||||||
|
return "CAP_NET_RAW"
|
||||||
|
case CAP_IPC_LOCK:
|
||||||
|
return "CAP_IPC_LOCK"
|
||||||
|
case CAP_IPC_OWNER:
|
||||||
|
return "CAP_IPC_OWNER"
|
||||||
|
case CAP_SYS_MODULE:
|
||||||
|
return "CAP_SYS_MODULE"
|
||||||
|
case CAP_SYS_RAWIO:
|
||||||
|
return "CAP_SYS_RAWIO"
|
||||||
|
case CAP_SYS_CHROOT:
|
||||||
|
return "CAP_SYS_CHROOT"
|
||||||
|
case CAP_SYS_PTRACE:
|
||||||
|
return "CAP_SYS_PTRACE"
|
||||||
|
case CAP_SYS_PACCT:
|
||||||
|
return "CAP_SYS_PACCT"
|
||||||
|
case CAP_SYS_ADMIN:
|
||||||
|
return "CAP_SYS_ADMIN"
|
||||||
|
case CAP_SYS_BOOT:
|
||||||
|
return "CAP_SYS_BOOT"
|
||||||
|
case CAP_SYS_NICE:
|
||||||
|
return "CAP_SYS_NICE"
|
||||||
|
case CAP_SYS_RESOURCE:
|
||||||
|
return "CAP_SYS_RESOURCE"
|
||||||
|
case CAP_SYS_TIME:
|
||||||
|
return "CAP_SYS_TIME"
|
||||||
|
case CAP_SYS_TTY_CONFIG:
|
||||||
|
return "CAP_SYS_TTY_CONFIG"
|
||||||
|
case CAP_MKNOD:
|
||||||
|
return "CAP_MKNOD"
|
||||||
|
case CAP_LEASE:
|
||||||
|
return "CAP_LEASE"
|
||||||
|
case CAP_AUDIT_WRITE:
|
||||||
|
return "CAP_AUDIT_WRITE"
|
||||||
|
case CAP_AUDIT_CONTROL:
|
||||||
|
return "CAP_AUDIT_CONTROL"
|
||||||
|
case CAP_SETFCAP:
|
||||||
|
return "CAP_SETFCAP"
|
||||||
|
case CAP_MAC_OVERRIDE:
|
||||||
|
return "CAP_MAC_OVERRIDE"
|
||||||
|
case CAP_MAC_ADMIN:
|
||||||
|
return "CAP_MAC_ADMIN"
|
||||||
|
case CAP_SYSLOG:
|
||||||
|
return "CAP_SYSLOG"
|
||||||
|
case CAP_WAKE_ALARM:
|
||||||
|
return "CAP_WAKE_ALARM"
|
||||||
|
case CAP_BLOCK_SUSPEND:
|
||||||
|
return "CAP_BLOCK_SUSPEND"
|
||||||
|
case CAP_AUDIT_READ:
|
||||||
|
return "CAP_AUDIT_READ"
|
||||||
|
default:
|
||||||
|
return "UNKNOWN"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// TrimmedString returns the capability name without the "CAP_" prefix.
|
||||||
|
func (cp Capability) TrimmedString() string {
|
||||||
|
const capPrefix = "CAP_"
|
||||||
|
s := cp.String()
|
||||||
|
if !strings.HasPrefix(s, capPrefix) {
|
||||||
|
return s
|
||||||
|
}
|
||||||
|
// This could use strings.TrimPrefix, but that function doesn't guarantee
|
||||||
|
// that it won't allocate a new string, whereas string slicing does.
|
||||||
|
// In the case of this function, since Capability.String returns a constant
|
||||||
|
// string, the underlying set of bytes backing that string will never be
|
||||||
|
// garbage-collected. Therefore, we always want to use a string slice that
|
||||||
|
// points to this same constant set of bytes, rather than risking
|
||||||
|
// allocating a new string.
|
||||||
|
return s[len(capPrefix):]
|
||||||
|
}
|
||||||
|
|
||||||
|
// CapabilityFromString converts a string to a capability.
|
||||||
|
// If the capability doesn't exist, its second return value is `false`.
|
||||||
|
// The capability name is expected to include the "CAP_" prefix.
|
||||||
|
func CapabilityFromString(capability string) (Capability, bool) {
|
||||||
|
for cp := Capability(0); cp <= CAP_LAST_CAP; cp++ {
|
||||||
|
if !cp.Ok() {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if cp.String() == capability {
|
||||||
|
return cp, true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return -1, false
|
||||||
|
}
|
||||||
|
|
||||||
|
// AllCapabilities returns a list of all defined capabilities.
|
||||||
|
func AllCapabilities() []Capability {
|
||||||
|
allCapapabilities := make([]Capability, 0, CAP_LAST_CAP+1)
|
||||||
|
for cp := Capability(0); cp <= CAP_LAST_CAP; cp++ {
|
||||||
|
if !cp.Ok() {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
allCapapabilities = append(allCapapabilities, cp)
|
||||||
|
}
|
||||||
|
return allCapapabilities
|
||||||
|
}
|
||||||
|
|
||||||
|
// Version numbers used by the capget/capset syscalls, defined in Linux's
|
||||||
|
// include/uapi/linux/capability.h.
|
||||||
|
const (
|
||||||
|
// LINUX_CAPABILITY_VERSION_1 causes the data pointer to be
|
||||||
|
// interpreted as a pointer to a single cap_user_data_t. Since capability
|
||||||
|
// sets are 64 bits and the "capability sets" in cap_user_data_t are 32
|
||||||
|
// bits only, this causes the upper 32 bits to be implicitly 0.
|
||||||
|
LINUX_CAPABILITY_VERSION_1 = 0x19980330
|
||||||
|
|
||||||
|
// LINUX_CAPABILITY_VERSION_2 and LINUX_CAPABILITY_VERSION_3 cause the
|
||||||
|
// data pointer to be interpreted as a pointer to an array of 2
|
||||||
|
// cap_user_data_t, using the second to store the 32 MSB of each capability
|
||||||
|
// set. Versions 2 and 3 are identical, but Linux printk's a warning on use
|
||||||
|
// of version 2 due to a userspace API defect.
|
||||||
|
LINUX_CAPABILITY_VERSION_2 = 0x20071026
|
||||||
|
LINUX_CAPABILITY_VERSION_3 = 0x20080522
|
||||||
|
|
||||||
|
// HighestCapabilityVersion is the highest supported
|
||||||
|
// LINUX_CAPABILITY_VERSION_* version.
|
||||||
|
HighestCapabilityVersion = LINUX_CAPABILITY_VERSION_3
|
||||||
|
)
|
||||||
|
|
||||||
|
// Constants that are used by file capability extended attributes, defined
|
||||||
|
// in Linux's include/uapi/linux/capability.h.
|
||||||
|
const (
|
||||||
|
// VFS_CAP_FLAGS_EFFECTIVE allows the effective capability set to be
|
||||||
|
// initialized with the permitted file capabilities.
|
||||||
|
VFS_CAP_FLAGS_EFFECTIVE = 0x000001
|
||||||
|
// VFS_CAP_REVISION_2 allows for file capability masks that are 64
|
||||||
|
// bits in size, and was necessary as the number of supported
|
||||||
|
// capabilities grew beyond 32.
|
||||||
|
VFS_CAP_REVISION_2 = 0x02000000
|
||||||
|
// VFS_CAP_REVISION_3 are provided to support namespaced file capabilities.
|
||||||
|
// As with version 2 file capabilities, version 3 capability
|
||||||
|
// masks are 64 bits in size. But in addition, the root user
|
||||||
|
// ID of namespace is encoded in the security.capability
|
||||||
|
// extended attribute.
|
||||||
|
VFS_CAP_REVISION_3 = 0x03000000
|
||||||
|
VFS_CAP_REVISION_MASK = 0xFF000000
|
||||||
|
// XATTR_CAPS_SZ_2 is sizeof(struct vfs_cap_data).
|
||||||
|
XATTR_CAPS_SZ_2 = 20
|
||||||
|
// XATTR_CAPS_SZ_3 is sizeof(struct vfs_ns_cap_data).
|
||||||
|
XATTR_CAPS_SZ_3 = 24
|
||||||
|
)
|
||||||
|
|
||||||
|
// VfsCapData is equivalent to Linux's struct vfs_cap_data.
|
||||||
|
//
|
||||||
|
// +marshal
|
||||||
|
type VfsCapData struct {
|
||||||
|
MagicEtc uint32
|
||||||
|
PermittedLo uint32
|
||||||
|
InheritableLo uint32
|
||||||
|
PermittedHi uint32
|
||||||
|
InheritableHi uint32
|
||||||
|
}
|
||||||
|
|
||||||
|
// Permitted returns the permitted capability set.
|
||||||
|
func (c *VfsCapData) Permitted() uint64 {
|
||||||
|
return uint64(c.PermittedHi)<<32 | uint64(c.PermittedLo)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Inheritable returns the inheritable capability set.
|
||||||
|
func (c *VfsCapData) Inheritable() uint64 {
|
||||||
|
return uint64(c.InheritableHi)<<32 | uint64(c.InheritableLo)
|
||||||
|
}
|
||||||
|
|
||||||
|
// IsRevision2 returns true if c is v2.
|
||||||
|
func (c *VfsCapData) IsRevision2() bool {
|
||||||
|
return (c.MagicEtc & VFS_CAP_REVISION_MASK) == VFS_CAP_REVISION_2
|
||||||
|
}
|
||||||
|
|
||||||
|
// ToString marshals c into bytes and returns it as a string.
|
||||||
|
func (c *VfsCapData) ToString() string {
|
||||||
|
buf := make([]byte, c.SizeBytes())
|
||||||
|
c.MarshalUnsafe(buf)
|
||||||
|
return string(buf)
|
||||||
|
}
|
||||||
|
|
||||||
|
// VfsNsCapData is equivalent to Linux's struct vfs_ns_cap_data.
|
||||||
|
//
|
||||||
|
// +marshal
|
||||||
|
type VfsNsCapData struct {
|
||||||
|
VfsCapData
|
||||||
|
RootID uint32
|
||||||
|
}
|
||||||
|
|
||||||
|
// ConvertToV3 converts c to v3 file capabilities.
|
||||||
|
func (c *VfsNsCapData) ConvertToV3(rootid uint32) {
|
||||||
|
c.RootID = rootid
|
||||||
|
if c.IsRevision2() {
|
||||||
|
// Change to v3 while retaining the effective bit.
|
||||||
|
c.MagicEtc = VFS_CAP_REVISION_3 | c.MagicEtc&VFS_CAP_FLAGS_EFFECTIVE
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ConvertToV2 converts c to v2 file capabilities.
|
||||||
|
func (c *VfsNsCapData) ConvertToV2() {
|
||||||
|
c.RootID = 0
|
||||||
|
if !c.IsRevision2() {
|
||||||
|
// Change to v2 while retaining the effective bit.
|
||||||
|
c.MagicEtc = VFS_CAP_REVISION_2 | c.MagicEtc&VFS_CAP_FLAGS_EFFECTIVE
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ToString marshals c into bytes and returns it as a string.
|
||||||
|
func (c *VfsNsCapData) ToString() string {
|
||||||
|
if c.IsRevision2() {
|
||||||
|
return c.VfsCapData.ToString()
|
||||||
|
}
|
||||||
|
buf := make([]byte, c.SizeBytes())
|
||||||
|
c.MarshalUnsafe(buf)
|
||||||
|
return string(buf)
|
||||||
|
}
|
||||||
|
|
||||||
|
// CapUserHeader is equivalent to Linux's cap_user_header_t.
|
||||||
|
//
|
||||||
|
// +marshal
|
||||||
|
type CapUserHeader struct {
|
||||||
|
Version uint32
|
||||||
|
Pid int32
|
||||||
|
}
|
||||||
|
|
||||||
|
// CapUserData is equivalent to Linux's cap_user_data_t.
|
||||||
|
//
|
||||||
|
// +marshal slice:CapUserDataSlice
|
||||||
|
type CapUserData struct {
|
||||||
|
Effective uint32
|
||||||
|
Permitted uint32
|
||||||
|
Inheritable uint32
|
||||||
|
}
|
||||||
71
pkg/abi/linux/clone.go
Normal file
71
pkg/abi/linux/clone.go
Normal file
|
|
@ -0,0 +1,71 @@
|
||||||
|
// Copyright 2018 The gVisor 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 linux
|
||||||
|
|
||||||
|
// Clone constants per clone(2).
|
||||||
|
const (
|
||||||
|
CSIGNAL = 0xff
|
||||||
|
|
||||||
|
CLONE_VM = 0x100
|
||||||
|
CLONE_FS = 0x200
|
||||||
|
CLONE_FILES = 0x400
|
||||||
|
CLONE_SIGHAND = 0x800
|
||||||
|
CLONE_PIDFD = 0x1000
|
||||||
|
CLONE_PTRACE = 0x2000
|
||||||
|
CLONE_VFORK = 0x4000
|
||||||
|
CLONE_PARENT = 0x8000
|
||||||
|
CLONE_THREAD = 0x10000
|
||||||
|
CLONE_NEWNS = 0x20000
|
||||||
|
CLONE_SYSVSEM = 0x40000
|
||||||
|
CLONE_SETTLS = 0x80000
|
||||||
|
CLONE_PARENT_SETTID = 0x100000
|
||||||
|
CLONE_CHILD_CLEARTID = 0x200000
|
||||||
|
CLONE_DETACHED = 0x400000
|
||||||
|
CLONE_UNTRACED = 0x800000
|
||||||
|
CLONE_CHILD_SETTID = 0x1000000
|
||||||
|
CLONE_NEWCGROUP = 0x2000000
|
||||||
|
CLONE_NEWUTS = 0x4000000
|
||||||
|
CLONE_NEWIPC = 0x8000000
|
||||||
|
CLONE_NEWUSER = 0x10000000
|
||||||
|
CLONE_NEWPID = 0x20000000
|
||||||
|
CLONE_NEWNET = 0x40000000
|
||||||
|
CLONE_IO = 0x80000000
|
||||||
|
|
||||||
|
// Only passable via clone3(2).
|
||||||
|
CLONE_CLEAR_SIGHAND = 0x100000000
|
||||||
|
CLONE_INTO_CGROUP = 0x200000000
|
||||||
|
|
||||||
|
// Sizeof first published struct.
|
||||||
|
CLONE_ARGS_SIZE_VER0 = 64
|
||||||
|
// Sizeof third published struct.
|
||||||
|
CLONE_ARGS_SIZE_VER2 = 88
|
||||||
|
)
|
||||||
|
|
||||||
|
// CloneArgs is struct clone_args, from include/uapi/linux/sched.h.
|
||||||
|
//
|
||||||
|
// +marshal
|
||||||
|
type CloneArgs struct {
|
||||||
|
Flags uint64
|
||||||
|
Pidfd uint64
|
||||||
|
ChildTID uint64
|
||||||
|
ParentTID uint64
|
||||||
|
ExitSignal uint64
|
||||||
|
Stack uint64
|
||||||
|
StackSize uint64
|
||||||
|
TLS uint64
|
||||||
|
SetTID uint64
|
||||||
|
SetTIDSize uint64
|
||||||
|
Cgroup uint64
|
||||||
|
}
|
||||||
36
pkg/abi/linux/context.go
Normal file
36
pkg/abi/linux/context.go
Normal file
|
|
@ -0,0 +1,36 @@
|
||||||
|
// Copyright 2021 The gVisor 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 linux
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/sagernet/gvisor/pkg/context"
|
||||||
|
)
|
||||||
|
|
||||||
|
// contextID is the linux package's type for context.Context.Value keys.
|
||||||
|
type contextID int
|
||||||
|
|
||||||
|
const (
|
||||||
|
// CtxSignalNoInfoFunc is a Context.Value key for a function to send signals.
|
||||||
|
CtxSignalNoInfoFunc contextID = iota
|
||||||
|
)
|
||||||
|
|
||||||
|
// SignalNoInfoFuncFromContext returns a callback function that can be used to send a
|
||||||
|
// signal to the given context.
|
||||||
|
func SignalNoInfoFuncFromContext(ctx context.Context) func(Signal) error {
|
||||||
|
if f := ctx.Value(CtxSignalNoInfoFunc); f != nil {
|
||||||
|
return f.(func(Signal) error)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
72
pkg/abi/linux/dev.go
Normal file
72
pkg/abi/linux/dev.go
Normal file
|
|
@ -0,0 +1,72 @@
|
||||||
|
// Copyright 2018 The gVisor 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 linux
|
||||||
|
|
||||||
|
// MakeDeviceID encodes a major and minor device number into a single device ID.
|
||||||
|
//
|
||||||
|
// Format (see linux/kdev_t.h:new_encode_dev):
|
||||||
|
//
|
||||||
|
// Bits 7:0 - minor bits 7:0
|
||||||
|
// Bits 19:8 - major bits 11:0
|
||||||
|
// Bits 31:20 - minor bits 19:8
|
||||||
|
func MakeDeviceID(major uint16, minor uint32) uint32 {
|
||||||
|
return (minor & 0xff) | ((uint32(major) & 0xfff) << 8) | ((minor >> 8) << 20)
|
||||||
|
}
|
||||||
|
|
||||||
|
// DecodeDeviceID decodes a device ID into major and minor device numbers.
|
||||||
|
func DecodeDeviceID(rdev uint32) (uint16, uint32) {
|
||||||
|
major := uint16((rdev >> 8) & 0xfff)
|
||||||
|
minor := (rdev & 0xff) | ((rdev >> 20) << 8)
|
||||||
|
return major, minor
|
||||||
|
}
|
||||||
|
|
||||||
|
// Character device IDs.
|
||||||
|
//
|
||||||
|
// See Documentations/devices.txt and uapi/linux/major.h.
|
||||||
|
const (
|
||||||
|
// UNNAMED_MAJOR is the major device number for "unnamed" devices, whose
|
||||||
|
// minor numbers are dynamically allocated by the kernel.
|
||||||
|
UNNAMED_MAJOR = 0
|
||||||
|
|
||||||
|
// MEM_MAJOR is the major device number for "memory" character devices.
|
||||||
|
MEM_MAJOR = 1
|
||||||
|
|
||||||
|
// TTYAUX_MAJOR is the major device number for alternate TTY devices.
|
||||||
|
TTYAUX_MAJOR = 5
|
||||||
|
|
||||||
|
// MISC_MAJOR is the major device number for non-serial mice, misc feature
|
||||||
|
// devices.
|
||||||
|
MISC_MAJOR = 10
|
||||||
|
|
||||||
|
// UNIX98_PTY_MASTER_MAJOR is the initial major device number for
|
||||||
|
// Unix98 PTY masters.
|
||||||
|
UNIX98_PTY_MASTER_MAJOR = 128
|
||||||
|
|
||||||
|
// UNIX98_PTY_REPLICA_MAJOR is the initial major device number for
|
||||||
|
// Unix98 PTY replicas.
|
||||||
|
UNIX98_PTY_REPLICA_MAJOR = 136
|
||||||
|
)
|
||||||
|
|
||||||
|
// Minor device numbers for TTYAUX_MAJOR.
|
||||||
|
const (
|
||||||
|
// PTMX_MINOR is the minor device number for /dev/ptmx.
|
||||||
|
PTMX_MINOR = 2
|
||||||
|
)
|
||||||
|
|
||||||
|
// from Linux include/drm/drm_accel.h
|
||||||
|
const (
|
||||||
|
// ACCEL_MAJOR is the major device number for compute accelerator devices.
|
||||||
|
ACCEL_MAJOR = 121
|
||||||
|
)
|
||||||
158
pkg/abi/linux/elf.go
Normal file
158
pkg/abi/linux/elf.go
Normal file
|
|
@ -0,0 +1,158 @@
|
||||||
|
// Copyright 2018 The gVisor 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 linux
|
||||||
|
|
||||||
|
// Linux auxiliary vector entry types.
|
||||||
|
const (
|
||||||
|
// AT_NULL is the end of the auxiliary vector.
|
||||||
|
AT_NULL = 0
|
||||||
|
|
||||||
|
// AT_IGNORE should be ignored.
|
||||||
|
AT_IGNORE = 1
|
||||||
|
|
||||||
|
// AT_EXECFD is the file descriptor of the program.
|
||||||
|
AT_EXECFD = 2
|
||||||
|
|
||||||
|
// AT_PHDR points to the program headers.
|
||||||
|
AT_PHDR = 3
|
||||||
|
|
||||||
|
// AT_PHENT is the size of a program header entry.
|
||||||
|
AT_PHENT = 4
|
||||||
|
|
||||||
|
// AT_PHNUM is the number of program headers.
|
||||||
|
AT_PHNUM = 5
|
||||||
|
|
||||||
|
// AT_PAGESZ is the system page size.
|
||||||
|
AT_PAGESZ = 6
|
||||||
|
|
||||||
|
// AT_BASE is the base address of the interpreter.
|
||||||
|
AT_BASE = 7
|
||||||
|
|
||||||
|
// AT_FLAGS are flags.
|
||||||
|
AT_FLAGS = 8
|
||||||
|
|
||||||
|
// AT_ENTRY is the program entry point.
|
||||||
|
AT_ENTRY = 9
|
||||||
|
|
||||||
|
// AT_NOTELF indicates that the program is not an ELF binary.
|
||||||
|
AT_NOTELF = 10
|
||||||
|
|
||||||
|
// AT_UID is the real UID.
|
||||||
|
AT_UID = 11
|
||||||
|
|
||||||
|
// AT_EUID is the effective UID.
|
||||||
|
AT_EUID = 12
|
||||||
|
|
||||||
|
// AT_GID is the real GID.
|
||||||
|
AT_GID = 13
|
||||||
|
|
||||||
|
// AT_EGID is the effective GID.
|
||||||
|
AT_EGID = 14
|
||||||
|
|
||||||
|
// AT_PLATFORM is a string identifying the CPU.
|
||||||
|
AT_PLATFORM = 15
|
||||||
|
|
||||||
|
// AT_HWCAP are arch-dependent CPU capabilities.
|
||||||
|
AT_HWCAP = 16
|
||||||
|
|
||||||
|
// AT_CLKTCK is the frequency used by times(2).
|
||||||
|
AT_CLKTCK = 17
|
||||||
|
|
||||||
|
// AT_SECURE indicate secure mode.
|
||||||
|
AT_SECURE = 23
|
||||||
|
|
||||||
|
// AT_BASE_PLATFORM is a string identifying the "real" platform. It may
|
||||||
|
// differ from AT_PLATFORM.
|
||||||
|
AT_BASE_PLATFORM = 24
|
||||||
|
|
||||||
|
// AT_RANDOM points to 16-bytes of random data.
|
||||||
|
AT_RANDOM = 25
|
||||||
|
|
||||||
|
// AT_HWCAP2 is an extension of AT_HWCAP.
|
||||||
|
AT_HWCAP2 = 26
|
||||||
|
|
||||||
|
// AT_EXECFN is the path used to execute the program.
|
||||||
|
AT_EXECFN = 31
|
||||||
|
|
||||||
|
// AT_SYSINFO_EHDR is the address of the VDSO.
|
||||||
|
AT_SYSINFO_EHDR = 33
|
||||||
|
)
|
||||||
|
|
||||||
|
// ELF ET_CORE and ptrace GETREGSET/SETREGSET register set types.
|
||||||
|
//
|
||||||
|
// See include/uapi/linux/elf.h.
|
||||||
|
const (
|
||||||
|
// NT_PRSTATUS is for general purpose register.
|
||||||
|
NT_PRSTATUS = 0x1
|
||||||
|
|
||||||
|
// NT_PRFPREG is for float point register.
|
||||||
|
NT_PRFPREG = 0x2
|
||||||
|
|
||||||
|
// NT_X86_XSTATE is for x86 extended state using xsave.
|
||||||
|
NT_X86_XSTATE = 0x202
|
||||||
|
|
||||||
|
// NT_ARM_TLS is for ARM TLS register.
|
||||||
|
NT_ARM_TLS = 0x401
|
||||||
|
)
|
||||||
|
|
||||||
|
// ElfHeader64 is the ELF64 file header.
|
||||||
|
//
|
||||||
|
// +marshal
|
||||||
|
type ElfHeader64 struct {
|
||||||
|
Ident [16]byte // File identification.
|
||||||
|
Type uint16 // File type.
|
||||||
|
Machine uint16 // Machine architecture.
|
||||||
|
Version uint32 // ELF format version.
|
||||||
|
Entry uint64 // Entry point.
|
||||||
|
Phoff uint64 // Program header file offset.
|
||||||
|
Shoff uint64 // Section header file offset.
|
||||||
|
Flags uint32 // Architecture-specific flags.
|
||||||
|
Ehsize uint16 // Size of ELF header in bytes.
|
||||||
|
Phentsize uint16 // Size of program header entry.
|
||||||
|
Phnum uint16 // Number of program header entries.
|
||||||
|
Shentsize uint16 // Size of section header entry.
|
||||||
|
Shnum uint16 // Number of section header entries.
|
||||||
|
Shstrndx uint16 // Section name strings section.
|
||||||
|
}
|
||||||
|
|
||||||
|
// ElfSection64 is the ELF64 Section header.
|
||||||
|
//
|
||||||
|
// +marshal
|
||||||
|
type ElfSection64 struct {
|
||||||
|
Name uint32 // Section name (index into the section header string table).
|
||||||
|
Type uint32 // Section type.
|
||||||
|
Flags uint64 // Section flags.
|
||||||
|
Addr uint64 // Address in memory image.
|
||||||
|
Off uint64 // Offset in file.
|
||||||
|
Size uint64 // Size in bytes.
|
||||||
|
Link uint32 // Index of a related section.
|
||||||
|
Info uint32 // Depends on section type.
|
||||||
|
Addralign uint64 // Alignment in bytes.
|
||||||
|
Entsize uint64 // Size of each entry in section.
|
||||||
|
}
|
||||||
|
|
||||||
|
// ElfProg64 is the ELF64 Program header.
|
||||||
|
//
|
||||||
|
// +marshal
|
||||||
|
type ElfProg64 struct {
|
||||||
|
Type uint32 // Entry type.
|
||||||
|
Flags uint32 // Access permission flags.
|
||||||
|
Off uint64 // File offset of contents.
|
||||||
|
Vaddr uint64 // Virtual address in memory image.
|
||||||
|
Paddr uint64 // Physical address (not used).
|
||||||
|
Filesz uint64 // Size of contents in file.
|
||||||
|
Memsz uint64 // Size of contents in memory.
|
||||||
|
Align uint64 // Alignment in memory and file.
|
||||||
|
}
|
||||||
58
pkg/abi/linux/epoll.go
Normal file
58
pkg/abi/linux/epoll.go
Normal file
|
|
@ -0,0 +1,58 @@
|
||||||
|
// Copyright 2019 The gVisor 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 linux
|
||||||
|
|
||||||
|
// Event masks.
|
||||||
|
const (
|
||||||
|
EPOLLIN = 0x1
|
||||||
|
EPOLLPRI = 0x2
|
||||||
|
EPOLLOUT = 0x4
|
||||||
|
EPOLLERR = 0x8
|
||||||
|
EPOLLHUP = 0x10
|
||||||
|
EPOLLRDNORM = 0x40
|
||||||
|
EPOLLRDBAND = 0x80
|
||||||
|
EPOLLWRNORM = 0x100
|
||||||
|
EPOLLWRBAND = 0x200
|
||||||
|
EPOLLMSG = 0x400
|
||||||
|
EPOLLRDHUP = 0x2000
|
||||||
|
)
|
||||||
|
|
||||||
|
// Per-file descriptor flags.
|
||||||
|
const (
|
||||||
|
EPOLLEXCLUSIVE = 1 << 28
|
||||||
|
EPOLLWAKEUP = 1 << 29
|
||||||
|
EPOLLONESHOT = 1 << 30
|
||||||
|
EPOLLET = 1 << 31
|
||||||
|
|
||||||
|
// EP_PRIVATE_BITS is fs/eventpoll.c:EP_PRIVATE_BITS, the set of all bits
|
||||||
|
// in an epoll event mask that correspond to flags rather than I/O events.
|
||||||
|
EP_PRIVATE_BITS = EPOLLEXCLUSIVE | EPOLLWAKEUP | EPOLLONESHOT | EPOLLET
|
||||||
|
)
|
||||||
|
|
||||||
|
// Operation flags.
|
||||||
|
const (
|
||||||
|
EPOLL_CLOEXEC = 0x80000
|
||||||
|
EPOLL_NONBLOCK = 0x800
|
||||||
|
)
|
||||||
|
|
||||||
|
// Control operations.
|
||||||
|
const (
|
||||||
|
EPOLL_CTL_ADD = 0x1
|
||||||
|
EPOLL_CTL_DEL = 0x2
|
||||||
|
EPOLL_CTL_MOD = 0x3
|
||||||
|
)
|
||||||
|
|
||||||
|
// SizeOfEpollEvent is the size of EpollEvent struct.
|
||||||
|
var SizeOfEpollEvent = (*EpollEvent)(nil).SizeBytes()
|
||||||
30
pkg/abi/linux/epoll_amd64.go
Normal file
30
pkg/abi/linux/epoll_amd64.go
Normal file
|
|
@ -0,0 +1,30 @@
|
||||||
|
// Copyright 2019 The gVisor 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.
|
||||||
|
|
||||||
|
//go:build amd64
|
||||||
|
// +build amd64
|
||||||
|
|
||||||
|
package linux
|
||||||
|
|
||||||
|
// EpollEvent is equivalent to struct epoll_event from epoll(2).
|
||||||
|
//
|
||||||
|
// +marshal slice:EpollEventSlice
|
||||||
|
type EpollEvent struct {
|
||||||
|
Events uint32
|
||||||
|
// Linux makes struct epoll_event::data a __u64. We represent it as
|
||||||
|
// [2]int32 because, on amd64, Linux also makes struct epoll_event
|
||||||
|
// __attribute__((packed)), such that there is no padding between Events
|
||||||
|
// and Data.
|
||||||
|
Data [2]int32
|
||||||
|
}
|
||||||
29
pkg/abi/linux/epoll_arm64.go
Normal file
29
pkg/abi/linux/epoll_arm64.go
Normal file
|
|
@ -0,0 +1,29 @@
|
||||||
|
// Copyright 2020 The gVisor 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.
|
||||||
|
|
||||||
|
//go:build arm64
|
||||||
|
// +build arm64
|
||||||
|
|
||||||
|
package linux
|
||||||
|
|
||||||
|
// EpollEvent is equivalent to struct epoll_event from epoll(2).
|
||||||
|
//
|
||||||
|
// +marshal slice:EpollEventSlice
|
||||||
|
type EpollEvent struct {
|
||||||
|
Events uint32
|
||||||
|
// Linux makes struct epoll_event a __u64, necessitating 4 bytes of padding
|
||||||
|
// here.
|
||||||
|
_ int32
|
||||||
|
Data [2]int32
|
||||||
|
}
|
||||||
187
pkg/abi/linux/errno/errno.go
Normal file
187
pkg/abi/linux/errno/errno.go
Normal file
|
|
@ -0,0 +1,187 @@
|
||||||
|
// Copyright 2018 The gVisor 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 errno holds errno codes for abi/linux.
|
||||||
|
package errno
|
||||||
|
|
||||||
|
// Errno represents a Linux errno value.
|
||||||
|
type Errno uint32
|
||||||
|
|
||||||
|
// Errno values from include/uapi/asm-generic/errno-base.h.
|
||||||
|
const (
|
||||||
|
NOERRNO = iota
|
||||||
|
EPERM
|
||||||
|
ENOENT
|
||||||
|
ESRCH
|
||||||
|
EINTR
|
||||||
|
EIO
|
||||||
|
ENXIO
|
||||||
|
E2BIG
|
||||||
|
ENOEXEC
|
||||||
|
EBADF
|
||||||
|
ECHILD // 10
|
||||||
|
EAGAIN
|
||||||
|
ENOMEM
|
||||||
|
EACCES
|
||||||
|
EFAULT
|
||||||
|
ENOTBLK
|
||||||
|
EBUSY
|
||||||
|
EEXIST
|
||||||
|
EXDEV
|
||||||
|
ENODEV
|
||||||
|
ENOTDIR // 20
|
||||||
|
EISDIR
|
||||||
|
EINVAL
|
||||||
|
ENFILE
|
||||||
|
EMFILE
|
||||||
|
ENOTTY
|
||||||
|
ETXTBSY
|
||||||
|
EFBIG
|
||||||
|
ENOSPC
|
||||||
|
ESPIPE
|
||||||
|
EROFS // 30
|
||||||
|
EMLINK
|
||||||
|
EPIPE
|
||||||
|
EDOM
|
||||||
|
ERANGE
|
||||||
|
// Errno values from include/uapi/asm-generic/errno.h.
|
||||||
|
EDEADLK
|
||||||
|
ENAMETOOLONG
|
||||||
|
ENOLCK
|
||||||
|
ENOSYS
|
||||||
|
ENOTEMPTY
|
||||||
|
ELOOP // 40
|
||||||
|
_ // Skip for EWOULDBLOCK = EAGAIN.
|
||||||
|
ENOMSG // 42
|
||||||
|
EIDRM
|
||||||
|
ECHRNG
|
||||||
|
EL2NSYNC
|
||||||
|
EL3HLT
|
||||||
|
EL3RST
|
||||||
|
ELNRNG
|
||||||
|
EUNATCH
|
||||||
|
ENOCSI
|
||||||
|
EL2HLT // 50
|
||||||
|
EBADE
|
||||||
|
EBADR
|
||||||
|
EXFULL
|
||||||
|
ENOANO
|
||||||
|
EBADRQC
|
||||||
|
EBADSLT
|
||||||
|
_ // Skip for EDEADLOCK = EDEADLK.
|
||||||
|
EBFONT
|
||||||
|
ENOSTR // 60
|
||||||
|
ENODATA
|
||||||
|
ETIME
|
||||||
|
ENOSR
|
||||||
|
ENONET
|
||||||
|
ENOPKG
|
||||||
|
EREMOTE
|
||||||
|
ENOLINK
|
||||||
|
EADV
|
||||||
|
ESRMNT
|
||||||
|
ECOMM // 70
|
||||||
|
EPROTO
|
||||||
|
EMULTIHOP
|
||||||
|
EDOTDOT
|
||||||
|
EBADMSG
|
||||||
|
EOVERFLOW
|
||||||
|
ENOTUNIQ
|
||||||
|
EBADFD
|
||||||
|
EREMCHG
|
||||||
|
ELIBACC
|
||||||
|
ELIBBAD // 80
|
||||||
|
ELIBSCN
|
||||||
|
ELIBMAX
|
||||||
|
ELIBEXEC
|
||||||
|
EILSEQ
|
||||||
|
ERESTART
|
||||||
|
ESTRPIPE
|
||||||
|
EUSERS
|
||||||
|
ENOTSOCK
|
||||||
|
EDESTADDRREQ
|
||||||
|
EMSGSIZE // 90
|
||||||
|
EPROTOTYPE
|
||||||
|
ENOPROTOOPT
|
||||||
|
EPROTONOSUPPORT
|
||||||
|
ESOCKTNOSUPPORT
|
||||||
|
EOPNOTSUPP
|
||||||
|
EPFNOSUPPORT
|
||||||
|
EAFNOSUPPORT
|
||||||
|
EADDRINUSE
|
||||||
|
EADDRNOTAVAIL
|
||||||
|
ENETDOWN // 100
|
||||||
|
ENETUNREACH
|
||||||
|
ENETRESET
|
||||||
|
ECONNABORTED
|
||||||
|
ECONNRESET
|
||||||
|
ENOBUFS
|
||||||
|
EISCONN
|
||||||
|
ENOTCONN
|
||||||
|
ESHUTDOWN
|
||||||
|
ETOOMANYREFS
|
||||||
|
ETIMEDOUT // 110
|
||||||
|
ECONNREFUSED
|
||||||
|
EHOSTDOWN
|
||||||
|
EHOSTUNREACH
|
||||||
|
EALREADY
|
||||||
|
EINPROGRESS
|
||||||
|
ESTALE
|
||||||
|
EUCLEAN
|
||||||
|
ENOTNAM
|
||||||
|
ENAVAIL
|
||||||
|
EISNAM // 120
|
||||||
|
EREMOTEIO
|
||||||
|
EDQUOT
|
||||||
|
ENOMEDIUM
|
||||||
|
EMEDIUMTYPE
|
||||||
|
ECANCELED
|
||||||
|
ENOKEY
|
||||||
|
EKEYEXPIRED
|
||||||
|
EKEYREVOKED
|
||||||
|
EKEYREJECTED
|
||||||
|
EOWNERDEAD // 130
|
||||||
|
ENOTRECOVERABLE
|
||||||
|
ERFKILL
|
||||||
|
EHWPOISON
|
||||||
|
)
|
||||||
|
|
||||||
|
// errnos derived from other errnos.
|
||||||
|
const (
|
||||||
|
EWOULDBLOCK = EAGAIN
|
||||||
|
EDEADLOCK = EDEADLK
|
||||||
|
)
|
||||||
|
|
||||||
|
// errnos for internal errors.
|
||||||
|
const (
|
||||||
|
// ERESTARTSYS is returned by an interrupted syscall to indicate that it
|
||||||
|
// should be converted to EINTR if interrupted by a signal delivered to a
|
||||||
|
// user handler without SA_RESTART set, and restarted otherwise.
|
||||||
|
ERESTARTSYS = 512
|
||||||
|
|
||||||
|
// ERESTARTNOINTR is returned by an interrupted syscall to indicate that it
|
||||||
|
// should always be restarted.
|
||||||
|
ERESTARTNOINTR = 513
|
||||||
|
|
||||||
|
// ERESTARTNOHAND is returned by an interrupted syscall to indicate that it
|
||||||
|
// should be converted to EINTR if interrupted by a signal delivered to a
|
||||||
|
// user handler, and restarted otherwise.
|
||||||
|
ERESTARTNOHAND = 514
|
||||||
|
|
||||||
|
// ERESTART_RESTARTBLOCK is returned by an interrupted syscall to indicate
|
||||||
|
// that it should be restarted using a custom function. The interrupted
|
||||||
|
// syscall must register a custom restart function by calling
|
||||||
|
// Task.SetRestartSyscallFn.
|
||||||
|
ERESTART_RESTARTBLOCK = 516
|
||||||
|
)
|
||||||
3
pkg/abi/linux/errno/errno_state_autogen.go
Normal file
3
pkg/abi/linux/errno/errno_state_autogen.go
Normal file
|
|
@ -0,0 +1,3 @@
|
||||||
|
// automatically generated by stateify.
|
||||||
|
|
||||||
|
package errno
|
||||||
93
pkg/abi/linux/errqueue.go
Normal file
93
pkg/abi/linux/errqueue.go
Normal file
|
|
@ -0,0 +1,93 @@
|
||||||
|
// Copyright 2020 The gVisor 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 linux
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/sagernet/gvisor/pkg/marshal"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Socket error origin codes as defined in include/uapi/linux/errqueue.h.
|
||||||
|
const (
|
||||||
|
SO_EE_ORIGIN_NONE = 0
|
||||||
|
SO_EE_ORIGIN_LOCAL = 1
|
||||||
|
SO_EE_ORIGIN_ICMP = 2
|
||||||
|
SO_EE_ORIGIN_ICMP6 = 3
|
||||||
|
)
|
||||||
|
|
||||||
|
// SockExtendedErr represents struct sock_extended_err in Linux defined in
|
||||||
|
// include/uapi/linux/errqueue.h.
|
||||||
|
//
|
||||||
|
// +marshal
|
||||||
|
type SockExtendedErr struct {
|
||||||
|
Errno uint32
|
||||||
|
Origin uint8
|
||||||
|
Type uint8
|
||||||
|
Code uint8
|
||||||
|
Pad uint8
|
||||||
|
Info uint32
|
||||||
|
Data uint32
|
||||||
|
}
|
||||||
|
|
||||||
|
// SockErrCMsg represents the IP*_RECVERR control message.
|
||||||
|
type SockErrCMsg interface {
|
||||||
|
marshal.Marshallable
|
||||||
|
|
||||||
|
CMsgLevel() uint32
|
||||||
|
CMsgType() uint32
|
||||||
|
}
|
||||||
|
|
||||||
|
// SockErrCMsgIPv4 is the IP_RECVERR control message used in
|
||||||
|
// recvmsg(MSG_ERRQUEUE) by ipv4 sockets. This is equilavent to `struct errhdr`
|
||||||
|
// defined in net/ipv4/ip_sockglue.c:ip_recv_error().
|
||||||
|
//
|
||||||
|
// +marshal
|
||||||
|
type SockErrCMsgIPv4 struct {
|
||||||
|
SockExtendedErr
|
||||||
|
Offender SockAddrInet
|
||||||
|
}
|
||||||
|
|
||||||
|
var _ SockErrCMsg = (*SockErrCMsgIPv4)(nil)
|
||||||
|
|
||||||
|
// CMsgLevel implements SockErrCMsg.CMsgLevel.
|
||||||
|
func (*SockErrCMsgIPv4) CMsgLevel() uint32 {
|
||||||
|
return SOL_IP
|
||||||
|
}
|
||||||
|
|
||||||
|
// CMsgType implements SockErrCMsg.CMsgType.
|
||||||
|
func (*SockErrCMsgIPv4) CMsgType() uint32 {
|
||||||
|
return IP_RECVERR
|
||||||
|
}
|
||||||
|
|
||||||
|
// SockErrCMsgIPv6 is the IPV6_RECVERR control message used in
|
||||||
|
// recvmsg(MSG_ERRQUEUE) by ipv6 sockets. This is equilavent to `struct errhdr`
|
||||||
|
// defined in net/ipv6/datagram.c:ipv6_recv_error().
|
||||||
|
//
|
||||||
|
// +marshal
|
||||||
|
type SockErrCMsgIPv6 struct {
|
||||||
|
SockExtendedErr
|
||||||
|
Offender SockAddrInet6
|
||||||
|
}
|
||||||
|
|
||||||
|
var _ SockErrCMsg = (*SockErrCMsgIPv6)(nil)
|
||||||
|
|
||||||
|
// CMsgLevel implements SockErrCMsg.CMsgLevel.
|
||||||
|
func (*SockErrCMsgIPv6) CMsgLevel() uint32 {
|
||||||
|
return SOL_IPV6
|
||||||
|
}
|
||||||
|
|
||||||
|
// CMsgType implements SockErrCMsg.CMsgType.
|
||||||
|
func (*SockErrCMsgIPv6) CMsgType() uint32 {
|
||||||
|
return IPV6_RECVERR
|
||||||
|
}
|
||||||
22
pkg/abi/linux/eventfd.go
Normal file
22
pkg/abi/linux/eventfd.go
Normal file
|
|
@ -0,0 +1,22 @@
|
||||||
|
// Copyright 2018 The gVisor 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 linux
|
||||||
|
|
||||||
|
// Constants for eventfd2(2).
|
||||||
|
const (
|
||||||
|
EFD_SEMAPHORE = 0x1
|
||||||
|
EFD_CLOEXEC = O_CLOEXEC
|
||||||
|
EFD_NONBLOCK = O_NONBLOCK
|
||||||
|
)
|
||||||
18
pkg/abi/linux/exec.go
Normal file
18
pkg/abi/linux/exec.go
Normal file
|
|
@ -0,0 +1,18 @@
|
||||||
|
// Copyright 2018 The gVisor 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 linux
|
||||||
|
|
||||||
|
// TASK_COMM_LEN is the task command name length.
|
||||||
|
const TASK_COMM_LEN = 16
|
||||||
25
pkg/abi/linux/fadvise.go
Normal file
25
pkg/abi/linux/fadvise.go
Normal file
|
|
@ -0,0 +1,25 @@
|
||||||
|
// Copyright 2020 The gVisor 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 linux
|
||||||
|
|
||||||
|
// Fadvise constants.
|
||||||
|
const (
|
||||||
|
POSIX_FADV_NORMAL = 0
|
||||||
|
POSIX_FADV_RANDOM = 1
|
||||||
|
POSIX_FADV_SEQUENTIAL = 2
|
||||||
|
POSIX_FADV_WILLNEED = 3
|
||||||
|
POSIX_FADV_DONTNEED = 4
|
||||||
|
POSIX_FADV_NOREUSE = 5
|
||||||
|
)
|
||||||
79
pkg/abi/linux/fcntl.go
Normal file
79
pkg/abi/linux/fcntl.go
Normal file
|
|
@ -0,0 +1,79 @@
|
||||||
|
// Copyright 2018 The gVisor 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 linux
|
||||||
|
|
||||||
|
// Commands from linux/fcntl.h.
|
||||||
|
const (
|
||||||
|
F_DUPFD = 0
|
||||||
|
F_GETFD = 1
|
||||||
|
F_SETFD = 2
|
||||||
|
F_GETFL = 3
|
||||||
|
F_SETFL = 4
|
||||||
|
F_GETLK = 5
|
||||||
|
F_SETLK = 6
|
||||||
|
F_SETLKW = 7
|
||||||
|
F_SETOWN = 8
|
||||||
|
F_GETOWN = 9
|
||||||
|
F_SETSIG = 10
|
||||||
|
F_GETSIG = 11
|
||||||
|
F_SETOWN_EX = 15
|
||||||
|
F_GETOWN_EX = 16
|
||||||
|
F_OFD_GETLK = 36
|
||||||
|
F_OFD_SETLK = 37
|
||||||
|
F_OFD_SETLKW = 38
|
||||||
|
F_DUPFD_CLOEXEC = 1024 + 6
|
||||||
|
F_SETPIPE_SZ = 1024 + 7
|
||||||
|
F_GETPIPE_SZ = 1024 + 8
|
||||||
|
)
|
||||||
|
|
||||||
|
// Commands for F_SETLK.
|
||||||
|
const (
|
||||||
|
F_RDLCK = 0
|
||||||
|
F_WRLCK = 1
|
||||||
|
F_UNLCK = 2
|
||||||
|
)
|
||||||
|
|
||||||
|
// Flags for fcntl.
|
||||||
|
const (
|
||||||
|
FD_CLOEXEC = 0o0000001
|
||||||
|
)
|
||||||
|
|
||||||
|
// Flock is the lock structure for F_SETLK.
|
||||||
|
//
|
||||||
|
// +marshal
|
||||||
|
type Flock struct {
|
||||||
|
Type int16
|
||||||
|
Whence int16
|
||||||
|
_ [4]byte
|
||||||
|
Start int64
|
||||||
|
Len int64
|
||||||
|
PID int32
|
||||||
|
_ [4]byte
|
||||||
|
}
|
||||||
|
|
||||||
|
// Owner types for F_SETOWN_EX and F_GETOWN_EX.
|
||||||
|
const (
|
||||||
|
F_OWNER_TID = 0
|
||||||
|
F_OWNER_PID = 1
|
||||||
|
F_OWNER_PGRP = 2
|
||||||
|
)
|
||||||
|
|
||||||
|
// FOwnerEx is the owner structure for F_SETOWN_EX and F_GETOWN_EX.
|
||||||
|
//
|
||||||
|
// +marshal
|
||||||
|
type FOwnerEx struct {
|
||||||
|
Type int32
|
||||||
|
PID int32
|
||||||
|
}
|
||||||
437
pkg/abi/linux/file.go
Normal file
437
pkg/abi/linux/file.go
Normal file
|
|
@ -0,0 +1,437 @@
|
||||||
|
// Copyright 2018 The gVisor 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 linux
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"github.com/sagernet/gvisor/pkg/abi"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Constants for open(2).
|
||||||
|
const (
|
||||||
|
O_ACCMODE = 0o00000003
|
||||||
|
O_RDONLY = 0o00000000
|
||||||
|
O_WRONLY = 0o00000001
|
||||||
|
O_RDWR = 0o00000002
|
||||||
|
O_CREAT = 0o00000100
|
||||||
|
O_EXCL = 0o00000200
|
||||||
|
O_NOCTTY = 0o00000400
|
||||||
|
O_TRUNC = 0o00001000
|
||||||
|
O_APPEND = 0o00002000
|
||||||
|
O_NONBLOCK = 0o00004000
|
||||||
|
O_DSYNC = 0o00010000
|
||||||
|
O_ASYNC = 0o00020000
|
||||||
|
O_NOATIME = 0o01000000
|
||||||
|
O_CLOEXEC = 0o02000000
|
||||||
|
O_SYNC = 0o04000000 // __O_SYNC in Linux
|
||||||
|
O_PATH = 0o10000000
|
||||||
|
O_TMPFILE = 0o20000000 // __O_TMPFILE in Linux
|
||||||
|
)
|
||||||
|
|
||||||
|
// Constants for fstatat(2).
|
||||||
|
const (
|
||||||
|
AT_SYMLINK_NOFOLLOW = 0x100
|
||||||
|
)
|
||||||
|
|
||||||
|
// Constants for mount(2).
|
||||||
|
const (
|
||||||
|
MS_RDONLY = 0x1
|
||||||
|
MS_NOSUID = 0x2
|
||||||
|
MS_NODEV = 0x4
|
||||||
|
MS_NOEXEC = 0x8
|
||||||
|
MS_SYNCHRONOUS = 0x10
|
||||||
|
MS_REMOUNT = 0x20
|
||||||
|
MS_MANDLOCK = 0x40
|
||||||
|
MS_DIRSYNC = 0x80
|
||||||
|
MS_NOATIME = 0x400
|
||||||
|
MS_NODIRATIME = 0x800
|
||||||
|
MS_BIND = 0x1000
|
||||||
|
MS_MOVE = 0x2000
|
||||||
|
MS_REC = 0x4000
|
||||||
|
|
||||||
|
MS_POSIXACL = 0x10000
|
||||||
|
MS_UNBINDABLE = 0x20000
|
||||||
|
MS_PRIVATE = 0x40000
|
||||||
|
MS_SLAVE = 0x80000
|
||||||
|
MS_SHARED = 0x100000
|
||||||
|
MS_RELATIME = 0x200000
|
||||||
|
MS_KERNMOUNT = 0x400000
|
||||||
|
MS_I_VERSION = 0x800000
|
||||||
|
MS_STRICTATIME = 0x1000000
|
||||||
|
|
||||||
|
MS_MGC_VAL = 0xC0ED0000
|
||||||
|
MS_MGC_MSK = 0xffff0000
|
||||||
|
)
|
||||||
|
|
||||||
|
// Constants for umount2(2).
|
||||||
|
const (
|
||||||
|
MNT_FORCE = 0x1
|
||||||
|
MNT_DETACH = 0x2
|
||||||
|
MNT_EXPIRE = 0x4
|
||||||
|
UMOUNT_NOFOLLOW = 0x8
|
||||||
|
)
|
||||||
|
|
||||||
|
// Constants for unlinkat(2).
|
||||||
|
const (
|
||||||
|
AT_REMOVEDIR = 0x200
|
||||||
|
)
|
||||||
|
|
||||||
|
// Constants for linkat(2) and fchownat(2).
|
||||||
|
const (
|
||||||
|
AT_SYMLINK_FOLLOW = 0x400
|
||||||
|
AT_EMPTY_PATH = 0x1000
|
||||||
|
)
|
||||||
|
|
||||||
|
// Constants for faccessat2(2).
|
||||||
|
const (
|
||||||
|
AT_EACCESS = 0x200
|
||||||
|
)
|
||||||
|
|
||||||
|
// Constants for all file-related ...at(2) syscalls.
|
||||||
|
const (
|
||||||
|
AT_FDCWD = -100
|
||||||
|
)
|
||||||
|
|
||||||
|
// Special values for the ns field in utimensat(2).
|
||||||
|
const (
|
||||||
|
UTIME_NOW = ((1 << 30) - 1)
|
||||||
|
UTIME_OMIT = ((1 << 30) - 2)
|
||||||
|
)
|
||||||
|
|
||||||
|
// MaxSymlinkTraversals is the maximum number of links that will be followed by
|
||||||
|
// the kernel to resolve a symlink.
|
||||||
|
const MaxSymlinkTraversals = 40
|
||||||
|
|
||||||
|
// Constants for flock(2).
|
||||||
|
const (
|
||||||
|
LOCK_SH = 1 // shared lock
|
||||||
|
LOCK_EX = 2 // exclusive lock
|
||||||
|
LOCK_NB = 4 // or'd with one of the above to prevent blocking
|
||||||
|
LOCK_UN = 8 // remove lock
|
||||||
|
)
|
||||||
|
|
||||||
|
// Values for mode_t.
|
||||||
|
const (
|
||||||
|
S_IFMT = 0o170000
|
||||||
|
S_IFSOCK = 0o140000
|
||||||
|
S_IFLNK = 0o120000
|
||||||
|
S_IFREG = 0o100000
|
||||||
|
S_IFBLK = 0o60000
|
||||||
|
S_IFDIR = 0o40000
|
||||||
|
S_IFCHR = 0o20000
|
||||||
|
S_IFIFO = 0o10000
|
||||||
|
|
||||||
|
FileTypeMask = S_IFMT
|
||||||
|
ModeSocket = S_IFSOCK
|
||||||
|
ModeSymlink = S_IFLNK
|
||||||
|
ModeRegular = S_IFREG
|
||||||
|
ModeBlockDevice = S_IFBLK
|
||||||
|
ModeDirectory = S_IFDIR
|
||||||
|
ModeCharacterDevice = S_IFCHR
|
||||||
|
ModeNamedPipe = S_IFIFO
|
||||||
|
|
||||||
|
S_ISUID = 0o4000
|
||||||
|
S_ISGID = 0o2000
|
||||||
|
S_ISVTX = 0o1000
|
||||||
|
|
||||||
|
ModeSetUID = S_ISUID
|
||||||
|
ModeSetGID = S_ISGID
|
||||||
|
ModeSticky = S_ISVTX
|
||||||
|
|
||||||
|
ModeUserAll = 0o700
|
||||||
|
ModeUserRead = 0o400
|
||||||
|
ModeUserWrite = 0o200
|
||||||
|
ModeUserExec = 0o100
|
||||||
|
ModeGroupAll = 0o070
|
||||||
|
ModeGroupRead = 0o040
|
||||||
|
ModeGroupWrite = 0o020
|
||||||
|
ModeGroupExec = 0o010
|
||||||
|
ModeOtherAll = 0o007
|
||||||
|
ModeOtherRead = 0o004
|
||||||
|
ModeOtherWrite = 0o002
|
||||||
|
ModeOtherExec = 0o001
|
||||||
|
PermissionsMask = 0o777
|
||||||
|
)
|
||||||
|
|
||||||
|
// Values for linux_dirent64.d_type.
|
||||||
|
const (
|
||||||
|
DT_UNKNOWN = 0
|
||||||
|
DT_FIFO = 1
|
||||||
|
DT_CHR = 2
|
||||||
|
DT_DIR = 4
|
||||||
|
DT_BLK = 6
|
||||||
|
DT_REG = 8
|
||||||
|
DT_LNK = 10
|
||||||
|
DT_SOCK = 12
|
||||||
|
DT_WHT = 14
|
||||||
|
)
|
||||||
|
|
||||||
|
// DirentType are the friendly strings for linux_dirent64.d_type.
|
||||||
|
var DirentType = abi.ValueSet{
|
||||||
|
DT_UNKNOWN: "DT_UNKNOWN",
|
||||||
|
DT_FIFO: "DT_FIFO",
|
||||||
|
DT_CHR: "DT_CHR",
|
||||||
|
DT_DIR: "DT_DIR",
|
||||||
|
DT_BLK: "DT_BLK",
|
||||||
|
DT_REG: "DT_REG",
|
||||||
|
DT_LNK: "DT_LNK",
|
||||||
|
DT_SOCK: "DT_SOCK",
|
||||||
|
DT_WHT: "DT_WHT",
|
||||||
|
}
|
||||||
|
|
||||||
|
// Values for fs on-disk file types.
|
||||||
|
const (
|
||||||
|
FT_UNKNOWN = 0
|
||||||
|
FT_REG_FILE = 1
|
||||||
|
FT_DIR = 2
|
||||||
|
FT_CHRDEV = 3
|
||||||
|
FT_BLKDEV = 4
|
||||||
|
FT_FIFO = 5
|
||||||
|
FT_SOCK = 6
|
||||||
|
FT_SYMLINK = 7
|
||||||
|
FT_MAX = 8
|
||||||
|
)
|
||||||
|
|
||||||
|
// Conversion from fs on-disk file type to dirent type.
|
||||||
|
var direntTypeByFileType = [FT_MAX]uint8{
|
||||||
|
FT_UNKNOWN: DT_UNKNOWN,
|
||||||
|
FT_REG_FILE: DT_REG,
|
||||||
|
FT_DIR: DT_DIR,
|
||||||
|
FT_CHRDEV: DT_CHR,
|
||||||
|
FT_BLKDEV: DT_BLK,
|
||||||
|
FT_FIFO: DT_FIFO,
|
||||||
|
FT_SOCK: DT_SOCK,
|
||||||
|
FT_SYMLINK: DT_LNK,
|
||||||
|
}
|
||||||
|
|
||||||
|
// FileTypeToDirentType converts the on-disk file type (FT_*) to the directory
|
||||||
|
// entry type (DT_*).
|
||||||
|
func FileTypeToDirentType(filetype uint8) uint8 {
|
||||||
|
if filetype >= FT_MAX {
|
||||||
|
return DT_UNKNOWN
|
||||||
|
}
|
||||||
|
return direntTypeByFileType[filetype]
|
||||||
|
}
|
||||||
|
|
||||||
|
// Values for preadv2/pwritev2.
|
||||||
|
const (
|
||||||
|
// NOTE(b/120162627): gVisor does not implement the RWF_HIPRI feature, but
|
||||||
|
// the flag is accepted as a valid flag argument for preadv2/pwritev2 and
|
||||||
|
// silently ignored.
|
||||||
|
RWF_HIPRI = 0x00000001
|
||||||
|
RWF_DSYNC = 0x00000002
|
||||||
|
RWF_SYNC = 0x00000004
|
||||||
|
RWF_VALID = RWF_HIPRI | RWF_DSYNC | RWF_SYNC
|
||||||
|
)
|
||||||
|
|
||||||
|
// SizeOfStat is the size of a Stat struct.
|
||||||
|
var SizeOfStat = (*Stat)(nil).SizeBytes()
|
||||||
|
|
||||||
|
// Flags for statx.
|
||||||
|
const (
|
||||||
|
AT_NO_AUTOMOUNT = 0x800
|
||||||
|
AT_STATX_SYNC_TYPE = 0x6000
|
||||||
|
AT_STATX_SYNC_AS_STAT = 0x0000
|
||||||
|
AT_STATX_FORCE_SYNC = 0x2000
|
||||||
|
AT_STATX_DONT_SYNC = 0x4000
|
||||||
|
)
|
||||||
|
|
||||||
|
// Mask values for statx.
|
||||||
|
const (
|
||||||
|
STATX_TYPE = 0x00000001
|
||||||
|
STATX_MODE = 0x00000002
|
||||||
|
STATX_NLINK = 0x00000004
|
||||||
|
STATX_UID = 0x00000008
|
||||||
|
STATX_GID = 0x00000010
|
||||||
|
STATX_ATIME = 0x00000020
|
||||||
|
STATX_MTIME = 0x00000040
|
||||||
|
STATX_CTIME = 0x00000080
|
||||||
|
STATX_INO = 0x00000100
|
||||||
|
STATX_SIZE = 0x00000200
|
||||||
|
STATX_BLOCKS = 0x00000400
|
||||||
|
STATX_BASIC_STATS = 0x000007ff
|
||||||
|
STATX_BTIME = 0x00000800
|
||||||
|
STATX_ALL = 0x00000fff
|
||||||
|
STATX__RESERVED = 0x80000000
|
||||||
|
)
|
||||||
|
|
||||||
|
// Bitmasks for Statx.Attributes and Statx.AttributesMask, from
|
||||||
|
// include/uapi/linux/stat.h.
|
||||||
|
const (
|
||||||
|
STATX_ATTR_COMPRESSED = 0x00000004
|
||||||
|
STATX_ATTR_IMMUTABLE = 0x00000010
|
||||||
|
STATX_ATTR_APPEND = 0x00000020
|
||||||
|
STATX_ATTR_NODUMP = 0x00000040
|
||||||
|
STATX_ATTR_ENCRYPTED = 0x00000800
|
||||||
|
STATX_ATTR_AUTOMOUNT = 0x00001000
|
||||||
|
)
|
||||||
|
|
||||||
|
// Statx represents struct statx.
|
||||||
|
//
|
||||||
|
// +marshal boundCheck slice:StatxSlice
|
||||||
|
type Statx struct {
|
||||||
|
Mask uint32
|
||||||
|
Blksize uint32
|
||||||
|
Attributes uint64
|
||||||
|
Nlink uint32
|
||||||
|
UID uint32
|
||||||
|
GID uint32
|
||||||
|
Mode uint16
|
||||||
|
_ uint16
|
||||||
|
Ino uint64
|
||||||
|
Size uint64
|
||||||
|
Blocks uint64
|
||||||
|
AttributesMask uint64
|
||||||
|
Atime StatxTimestamp
|
||||||
|
Btime StatxTimestamp
|
||||||
|
Ctime StatxTimestamp
|
||||||
|
Mtime StatxTimestamp
|
||||||
|
RdevMajor uint32
|
||||||
|
RdevMinor uint32
|
||||||
|
DevMajor uint32
|
||||||
|
DevMinor uint32
|
||||||
|
}
|
||||||
|
|
||||||
|
// String implements fmt.Stringer.String.
|
||||||
|
func (s *Statx) String() string {
|
||||||
|
return fmt.Sprintf("Statx{Mask: %#x, Mode: %s, UID: %d, GID: %d, Ino: %d, DevMajor: %d, DevMinor: %d, Size: %d, Blocks: %d, Blksize: %d, Nlink: %d, Atime: %s, Btime: %s, Ctime: %s, Mtime: %s, Attributes: %d, AttributesMask: %d, RdevMajor: %d, RdevMinor: %d}",
|
||||||
|
s.Mask, FileMode(s.Mode), s.UID, s.GID, s.Ino, s.DevMajor, s.DevMinor, s.Size, s.Blocks, s.Blksize, s.Nlink, s.Atime.ToTime(), s.Btime.ToTime(), s.Ctime.ToTime(), s.Mtime.ToTime(), s.Attributes, s.AttributesMask, s.RdevMajor, s.RdevMinor)
|
||||||
|
}
|
||||||
|
|
||||||
|
// SizeOfStatx is the size of a Statx struct.
|
||||||
|
var SizeOfStatx = (*Statx)(nil).SizeBytes()
|
||||||
|
|
||||||
|
// FileMode represents a mode_t.
|
||||||
|
//
|
||||||
|
// +marshal
|
||||||
|
type FileMode uint16
|
||||||
|
|
||||||
|
// Permissions returns just the permission bits.
|
||||||
|
func (m FileMode) Permissions() FileMode {
|
||||||
|
return m & PermissionsMask
|
||||||
|
}
|
||||||
|
|
||||||
|
// FileType returns just the file type bits.
|
||||||
|
func (m FileMode) FileType() FileMode {
|
||||||
|
return m & FileTypeMask
|
||||||
|
}
|
||||||
|
|
||||||
|
// ExtraBits returns everything but the file type and permission bits.
|
||||||
|
func (m FileMode) ExtraBits() FileMode {
|
||||||
|
return m &^ (PermissionsMask | FileTypeMask)
|
||||||
|
}
|
||||||
|
|
||||||
|
// IsDir returns true if file type represents a directory.
|
||||||
|
func (m FileMode) IsDir() bool {
|
||||||
|
return m.FileType() == S_IFDIR
|
||||||
|
}
|
||||||
|
|
||||||
|
// String returns a string representation of m.
|
||||||
|
func (m FileMode) String() string {
|
||||||
|
var s []string
|
||||||
|
if ft := m.FileType(); ft != 0 {
|
||||||
|
s = append(s, fileType.Parse(uint64(ft)))
|
||||||
|
}
|
||||||
|
if eb := m.ExtraBits(); eb != 0 {
|
||||||
|
s = append(s, modeExtraBits.Parse(uint64(eb)))
|
||||||
|
}
|
||||||
|
s = append(s, fmt.Sprintf("0o%o", m.Permissions()))
|
||||||
|
return strings.Join(s, "|")
|
||||||
|
}
|
||||||
|
|
||||||
|
// DirentType maps file types to dirent types appropriate for (struct
|
||||||
|
// dirent)::d_type.
|
||||||
|
func (m FileMode) DirentType() uint8 {
|
||||||
|
switch m.FileType() {
|
||||||
|
case ModeSocket:
|
||||||
|
return DT_SOCK
|
||||||
|
case ModeSymlink:
|
||||||
|
return DT_LNK
|
||||||
|
case ModeRegular:
|
||||||
|
return DT_REG
|
||||||
|
case ModeBlockDevice:
|
||||||
|
return DT_BLK
|
||||||
|
case ModeDirectory:
|
||||||
|
return DT_DIR
|
||||||
|
case ModeCharacterDevice:
|
||||||
|
return DT_CHR
|
||||||
|
case ModeNamedPipe:
|
||||||
|
return DT_FIFO
|
||||||
|
default:
|
||||||
|
return DT_UNKNOWN
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var modeExtraBits = abi.FlagSet{
|
||||||
|
{
|
||||||
|
Flag: ModeSetUID,
|
||||||
|
Name: "S_ISUID",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Flag: ModeSetGID,
|
||||||
|
Name: "S_ISGID",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Flag: ModeSticky,
|
||||||
|
Name: "S_ISVTX",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
var fileType = abi.ValueSet{
|
||||||
|
ModeSocket: "S_IFSOCK",
|
||||||
|
ModeSymlink: "S_IFLINK",
|
||||||
|
ModeRegular: "S_IFREG",
|
||||||
|
ModeBlockDevice: "S_IFBLK",
|
||||||
|
ModeDirectory: "S_IFDIR",
|
||||||
|
ModeCharacterDevice: "S_IFCHR",
|
||||||
|
ModeNamedPipe: "S_IFIFO",
|
||||||
|
}
|
||||||
|
|
||||||
|
// Constants for memfd_create(2). Source: include/uapi/linux/memfd.h
|
||||||
|
const (
|
||||||
|
MFD_CLOEXEC = 0x0001
|
||||||
|
MFD_ALLOW_SEALING = 0x0002
|
||||||
|
)
|
||||||
|
|
||||||
|
// Constants related to file seals. Source: include/uapi/{asm-generic,linux}/fcntl.h
|
||||||
|
const (
|
||||||
|
F_LINUX_SPECIFIC_BASE = 1024
|
||||||
|
F_ADD_SEALS = F_LINUX_SPECIFIC_BASE + 9
|
||||||
|
F_GET_SEALS = F_LINUX_SPECIFIC_BASE + 10
|
||||||
|
|
||||||
|
F_SEAL_SEAL = 0x0001 // Prevent further seals from being set.
|
||||||
|
F_SEAL_SHRINK = 0x0002 // Prevent file from shrinking.
|
||||||
|
F_SEAL_GROW = 0x0004 // Prevent file from growing.
|
||||||
|
F_SEAL_WRITE = 0x0008 // Prevent writes.
|
||||||
|
)
|
||||||
|
|
||||||
|
// Constants related to fallocate(2). Source: include/uapi/linux/falloc.h
|
||||||
|
const (
|
||||||
|
FALLOC_FL_KEEP_SIZE = 0x01
|
||||||
|
FALLOC_FL_PUNCH_HOLE = 0x02
|
||||||
|
FALLOC_FL_NO_HIDE_STALE = 0x04
|
||||||
|
FALLOC_FL_COLLAPSE_RANGE = 0x08
|
||||||
|
FALLOC_FL_ZERO_RANGE = 0x10
|
||||||
|
FALLOC_FL_INSERT_RANGE = 0x20
|
||||||
|
FALLOC_FL_UNSHARE_RANGE = 0x40
|
||||||
|
)
|
||||||
|
|
||||||
|
// Constants related to close_range(2). Source: /include/uapi/linux/close_range.h
|
||||||
|
const (
|
||||||
|
CLOSE_RANGE_UNSHARE = uint32(1 << 1)
|
||||||
|
CLOSE_RANGE_CLOEXEC = uint32(1 << 2)
|
||||||
|
)
|
||||||
47
pkg/abi/linux/file_amd64.go
Normal file
47
pkg/abi/linux/file_amd64.go
Normal file
|
|
@ -0,0 +1,47 @@
|
||||||
|
// Copyright 2018 The gVisor 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.
|
||||||
|
|
||||||
|
//go:build amd64
|
||||||
|
// +build amd64
|
||||||
|
|
||||||
|
package linux
|
||||||
|
|
||||||
|
// Constants for open(2).
|
||||||
|
const (
|
||||||
|
O_DIRECT = 0o00040000
|
||||||
|
O_LARGEFILE = 0o00100000
|
||||||
|
O_DIRECTORY = 0o00200000
|
||||||
|
O_NOFOLLOW = 0o00400000
|
||||||
|
)
|
||||||
|
|
||||||
|
// Stat represents struct stat.
|
||||||
|
//
|
||||||
|
// +marshal
|
||||||
|
type Stat struct {
|
||||||
|
Dev uint64
|
||||||
|
Ino uint64
|
||||||
|
Nlink uint64
|
||||||
|
Mode uint32
|
||||||
|
UID uint32
|
||||||
|
GID uint32
|
||||||
|
_ int32
|
||||||
|
Rdev uint64
|
||||||
|
Size int64
|
||||||
|
Blksize int64
|
||||||
|
Blocks int64
|
||||||
|
ATime Timespec
|
||||||
|
MTime Timespec
|
||||||
|
CTime Timespec
|
||||||
|
_ [3]int64
|
||||||
|
}
|
||||||
48
pkg/abi/linux/file_arm64.go
Normal file
48
pkg/abi/linux/file_arm64.go
Normal file
|
|
@ -0,0 +1,48 @@
|
||||||
|
// Copyright 2019 The gVisor 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.
|
||||||
|
|
||||||
|
//go:build arm64
|
||||||
|
// +build arm64
|
||||||
|
|
||||||
|
package linux
|
||||||
|
|
||||||
|
// Constants for open(2).
|
||||||
|
const (
|
||||||
|
O_DIRECTORY = 0o00040000
|
||||||
|
O_NOFOLLOW = 0o00100000
|
||||||
|
O_DIRECT = 0o00200000
|
||||||
|
O_LARGEFILE = 0o00400000
|
||||||
|
)
|
||||||
|
|
||||||
|
// Stat represents struct stat.
|
||||||
|
//
|
||||||
|
// +marshal
|
||||||
|
type Stat struct {
|
||||||
|
Dev uint64
|
||||||
|
Ino uint64
|
||||||
|
Mode uint32
|
||||||
|
Nlink uint32
|
||||||
|
UID uint32
|
||||||
|
GID uint32
|
||||||
|
Rdev uint64
|
||||||
|
_ uint64
|
||||||
|
Size int64
|
||||||
|
Blksize int32
|
||||||
|
_ int32
|
||||||
|
Blocks int64
|
||||||
|
ATime Timespec
|
||||||
|
MTime Timespec
|
||||||
|
CTime Timespec
|
||||||
|
_ [2]int32
|
||||||
|
}
|
||||||
129
pkg/abi/linux/fs.go
Normal file
129
pkg/abi/linux/fs.go
Normal file
|
|
@ -0,0 +1,129 @@
|
||||||
|
// Copyright 2018 The gVisor 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 linux
|
||||||
|
|
||||||
|
// Filesystem types used in statfs(2).
|
||||||
|
//
|
||||||
|
// See linux/magic.h.
|
||||||
|
const (
|
||||||
|
ANON_INODE_FS_MAGIC = 0x09041934
|
||||||
|
CGROUP_SUPER_MAGIC = 0x27e0eb
|
||||||
|
DEVPTS_SUPER_MAGIC = 0x00001cd1
|
||||||
|
EXT_SUPER_MAGIC = 0xef53
|
||||||
|
FUSE_SUPER_MAGIC = 0x65735546
|
||||||
|
MQUEUE_MAGIC = 0x19800202
|
||||||
|
NSFS_MAGIC = 0x6e736673
|
||||||
|
OVERLAYFS_SUPER_MAGIC = 0x794c7630
|
||||||
|
PIPEFS_MAGIC = 0x50495045
|
||||||
|
PROC_SUPER_MAGIC = 0x9fa0
|
||||||
|
RAMFS_MAGIC = 0x09041934
|
||||||
|
SOCKFS_MAGIC = 0x534F434B
|
||||||
|
SYSFS_MAGIC = 0x62656572
|
||||||
|
TMPFS_MAGIC = 0x01021994
|
||||||
|
V9FS_MAGIC = 0x01021997
|
||||||
|
)
|
||||||
|
|
||||||
|
// Filesystem path limits, from uapi/linux/limits.h.
|
||||||
|
const (
|
||||||
|
NAME_MAX = 255
|
||||||
|
PATH_MAX = 4096
|
||||||
|
)
|
||||||
|
|
||||||
|
// The bit mask f_flags in struct statfs, from include/linux/statfs.h
|
||||||
|
const (
|
||||||
|
ST_RDONLY = 0x0001
|
||||||
|
ST_NOSUID = 0x0002
|
||||||
|
ST_NODEV = 0x0004
|
||||||
|
ST_NOEXEC = 0x0008
|
||||||
|
ST_SYNCHRONOUS = 0x0010
|
||||||
|
ST_VALID = 0x0020
|
||||||
|
ST_MANDLOCK = 0x0040
|
||||||
|
ST_NOATIME = 0x0400
|
||||||
|
ST_NODIRATIME = 0x0800
|
||||||
|
ST_RELATIME = 0x1000
|
||||||
|
ST_NOSYMFOLLOW = 0x2000
|
||||||
|
)
|
||||||
|
|
||||||
|
// Statfs is struct statfs, from uapi/asm-generic/statfs.h.
|
||||||
|
//
|
||||||
|
// +marshal
|
||||||
|
type Statfs struct {
|
||||||
|
// Type is one of the filesystem magic values, defined above.
|
||||||
|
Type uint64
|
||||||
|
|
||||||
|
// BlockSize is the optimal transfer block size in bytes.
|
||||||
|
BlockSize int64
|
||||||
|
|
||||||
|
// Blocks is the maximum number of data blocks the filesystem may store, in
|
||||||
|
// units of BlockSize.
|
||||||
|
Blocks uint64
|
||||||
|
|
||||||
|
// BlocksFree is the number of free data blocks, in units of BlockSize.
|
||||||
|
BlocksFree uint64
|
||||||
|
|
||||||
|
// BlocksAvailable is the number of data blocks free for use by
|
||||||
|
// unprivileged users, in units of BlockSize.
|
||||||
|
BlocksAvailable uint64
|
||||||
|
|
||||||
|
// Files is the number of used file nodes on the filesystem.
|
||||||
|
Files uint64
|
||||||
|
|
||||||
|
// FileFress is the number of free file nodes on the filesystem.
|
||||||
|
FilesFree uint64
|
||||||
|
|
||||||
|
// FSID is the filesystem ID.
|
||||||
|
FSID [2]int32
|
||||||
|
|
||||||
|
// NameLength is the maximum file name length.
|
||||||
|
NameLength uint64
|
||||||
|
|
||||||
|
// FragmentSize is equivalent to BlockSize.
|
||||||
|
FragmentSize int64
|
||||||
|
|
||||||
|
// Flags is the set of filesystem mount flags.
|
||||||
|
Flags uint64
|
||||||
|
|
||||||
|
// Spare is unused.
|
||||||
|
Spare [4]uint64
|
||||||
|
}
|
||||||
|
|
||||||
|
// Whence argument to lseek(2), from include/uapi/linux/fs.h.
|
||||||
|
const (
|
||||||
|
SEEK_SET = 0
|
||||||
|
SEEK_CUR = 1
|
||||||
|
SEEK_END = 2
|
||||||
|
SEEK_DATA = 3
|
||||||
|
SEEK_HOLE = 4
|
||||||
|
)
|
||||||
|
|
||||||
|
// Sync_file_range flags, from include/uapi/linux/fs.h
|
||||||
|
const (
|
||||||
|
SYNC_FILE_RANGE_WAIT_BEFORE = 1
|
||||||
|
SYNC_FILE_RANGE_WRITE = 2
|
||||||
|
SYNC_FILE_RANGE_WAIT_AFTER = 4
|
||||||
|
)
|
||||||
|
|
||||||
|
// Flag argument to renameat2(2), from include/uapi/linux/fs.h.
|
||||||
|
const (
|
||||||
|
RENAME_NOREPLACE = (1 << 0) // Don't overwrite target.
|
||||||
|
RENAME_EXCHANGE = (1 << 1) // Exchange src and dst.
|
||||||
|
RENAME_WHITEOUT = (1 << 2) // Whiteout src.
|
||||||
|
)
|
||||||
|
|
||||||
|
// Overlayfs constants from include/linux/fs.h.
|
||||||
|
const (
|
||||||
|
WHITEOUT_MODE = 0
|
||||||
|
WHITEOUT_DEV = 0
|
||||||
|
)
|
||||||
1139
pkg/abi/linux/fuse.go
Normal file
1139
pkg/abi/linux/fuse.go
Normal file
File diff suppressed because it is too large
Load diff
80
pkg/abi/linux/futex.go
Normal file
80
pkg/abi/linux/futex.go
Normal file
|
|
@ -0,0 +1,80 @@
|
||||||
|
// Copyright 2018 The gVisor 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 linux
|
||||||
|
|
||||||
|
// From <linux/futex.h> and <sys/time.h>.
|
||||||
|
// Flags are used in syscall futex(2).
|
||||||
|
const (
|
||||||
|
FUTEX_WAIT = 0
|
||||||
|
FUTEX_WAKE = 1
|
||||||
|
FUTEX_FD = 2
|
||||||
|
FUTEX_REQUEUE = 3
|
||||||
|
FUTEX_CMP_REQUEUE = 4
|
||||||
|
FUTEX_WAKE_OP = 5
|
||||||
|
FUTEX_LOCK_PI = 6
|
||||||
|
FUTEX_UNLOCK_PI = 7
|
||||||
|
FUTEX_TRYLOCK_PI = 8
|
||||||
|
FUTEX_WAIT_BITSET = 9
|
||||||
|
FUTEX_WAKE_BITSET = 10
|
||||||
|
FUTEX_WAIT_REQUEUE_PI = 11
|
||||||
|
FUTEX_CMP_REQUEUE_PI = 12
|
||||||
|
|
||||||
|
FUTEX_PRIVATE_FLAG = 128
|
||||||
|
FUTEX_CLOCK_REALTIME = 256
|
||||||
|
)
|
||||||
|
|
||||||
|
// These are flags are from <linux/futex.h> and are used in FUTEX_WAKE_OP
|
||||||
|
// to define the operations.
|
||||||
|
const (
|
||||||
|
FUTEX_OP_SET = 0
|
||||||
|
FUTEX_OP_ADD = 1
|
||||||
|
FUTEX_OP_OR = 2
|
||||||
|
FUTEX_OP_ANDN = 3
|
||||||
|
FUTEX_OP_XOR = 4
|
||||||
|
FUTEX_OP_OPARG_SHIFT = 8
|
||||||
|
FUTEX_OP_CMP_EQ = 0
|
||||||
|
FUTEX_OP_CMP_NE = 1
|
||||||
|
FUTEX_OP_CMP_LT = 2
|
||||||
|
FUTEX_OP_CMP_LE = 3
|
||||||
|
FUTEX_OP_CMP_GT = 4
|
||||||
|
FUTEX_OP_CMP_GE = 5
|
||||||
|
)
|
||||||
|
|
||||||
|
// FUTEX_TID_MASK is the TID portion of a PI futex word.
|
||||||
|
const FUTEX_TID_MASK = 0x3fffffff
|
||||||
|
|
||||||
|
// Constants used for priority-inheritance futexes.
|
||||||
|
const (
|
||||||
|
FUTEX_WAITERS = 0x80000000
|
||||||
|
FUTEX_OWNER_DIED = 0x40000000
|
||||||
|
)
|
||||||
|
|
||||||
|
// FUTEX_BITSET_MATCH_ANY has all bits set.
|
||||||
|
const FUTEX_BITSET_MATCH_ANY = 0xffffffff
|
||||||
|
|
||||||
|
// ROBUST_LIST_LIMIT protects against a deliberately circular list.
|
||||||
|
const ROBUST_LIST_LIMIT = 2048
|
||||||
|
|
||||||
|
// RobustListHead corresponds to Linux's struct robust_list_head.
|
||||||
|
//
|
||||||
|
// +marshal
|
||||||
|
type RobustListHead struct {
|
||||||
|
List uint64
|
||||||
|
FutexOffset uint64
|
||||||
|
ListOpPending uint64
|
||||||
|
}
|
||||||
|
|
||||||
|
// SizeOfRobustListHead is the size of a RobustListHead struct.
|
||||||
|
var SizeOfRobustListHead = (*RobustListHead)(nil).SizeBytes()
|
||||||
97
pkg/abi/linux/inotify.go
Normal file
97
pkg/abi/linux/inotify.go
Normal file
|
|
@ -0,0 +1,97 @@
|
||||||
|
// Copyright 2018 The gVisor 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 linux
|
||||||
|
|
||||||
|
// Inotify events observable by userspace. These directly correspond to
|
||||||
|
// filesystem operations and there may only be a single of them per inotify
|
||||||
|
// event read from an inotify fd.
|
||||||
|
const (
|
||||||
|
// IN_ACCESS indicates a file was accessed.
|
||||||
|
IN_ACCESS = 0x00000001
|
||||||
|
// IN_MODIFY indicates a file was modified.
|
||||||
|
IN_MODIFY = 0x00000002
|
||||||
|
// IN_ATTRIB indicates a watch target's metadata changed.
|
||||||
|
IN_ATTRIB = 0x00000004
|
||||||
|
// IN_CLOSE_WRITE indicates a writable file was closed.
|
||||||
|
IN_CLOSE_WRITE = 0x00000008
|
||||||
|
// IN_CLOSE_NOWRITE indicates a non-writable file was closed.
|
||||||
|
IN_CLOSE_NOWRITE = 0x00000010
|
||||||
|
// IN_OPEN indicates a file was opened.
|
||||||
|
IN_OPEN = 0x00000020
|
||||||
|
// IN_MOVED_FROM indicates a file was moved from X.
|
||||||
|
IN_MOVED_FROM = 0x00000040
|
||||||
|
// IN_MOVED_TO indicates a file was moved to Y.
|
||||||
|
IN_MOVED_TO = 0x00000080
|
||||||
|
// IN_CREATE indicates a file was created in a watched directory.
|
||||||
|
IN_CREATE = 0x00000100
|
||||||
|
// IN_DELETE indicates a file was deleted in a watched directory.
|
||||||
|
IN_DELETE = 0x00000200
|
||||||
|
// IN_DELETE_SELF indicates a watch target itself was deleted.
|
||||||
|
IN_DELETE_SELF = 0x00000400
|
||||||
|
// IN_MOVE_SELF indicates a watch target itself was moved.
|
||||||
|
IN_MOVE_SELF = 0x00000800
|
||||||
|
// IN_ALL_EVENTS is a mask for all observable userspace events.
|
||||||
|
IN_ALL_EVENTS = 0x00000fff
|
||||||
|
)
|
||||||
|
|
||||||
|
// Inotify control events. These may be present in their own events, or ORed
|
||||||
|
// with other observable events.
|
||||||
|
const (
|
||||||
|
// IN_UNMOUNT indicates the backing filesystem was unmounted.
|
||||||
|
IN_UNMOUNT = 0x00002000
|
||||||
|
// IN_Q_OVERFLOW indicates the event queued overflowed.
|
||||||
|
IN_Q_OVERFLOW = 0x00004000
|
||||||
|
// IN_IGNORED indicates a watch was removed, either implicitly or through
|
||||||
|
// inotify_rm_watch(2).
|
||||||
|
IN_IGNORED = 0x00008000
|
||||||
|
// IN_ISDIR indicates the subject of an event was a directory.
|
||||||
|
IN_ISDIR = 0x40000000
|
||||||
|
)
|
||||||
|
|
||||||
|
// Feature flags for inotify_add_watch(2).
|
||||||
|
const (
|
||||||
|
// IN_ONLYDIR indicates that a path should be watched only if it's a
|
||||||
|
// directory.
|
||||||
|
IN_ONLYDIR = 0x01000000
|
||||||
|
// IN_DONT_FOLLOW indicates that the watch path shouldn't be resolved if
|
||||||
|
// it's a symlink.
|
||||||
|
IN_DONT_FOLLOW = 0x02000000
|
||||||
|
// IN_EXCL_UNLINK indicates events to this watch from unlinked objects
|
||||||
|
// should be filtered out.
|
||||||
|
IN_EXCL_UNLINK = 0x04000000
|
||||||
|
// IN_MASK_ADD indicates the provided mask should be ORed into any existing
|
||||||
|
// watch on the provided path.
|
||||||
|
IN_MASK_ADD = 0x20000000
|
||||||
|
// IN_ONESHOT indicates the watch should be removed after one event.
|
||||||
|
IN_ONESHOT = 0x80000000
|
||||||
|
)
|
||||||
|
|
||||||
|
// Feature flags for inotify_init1(2).
|
||||||
|
const (
|
||||||
|
// IN_CLOEXEC is an alias for O_CLOEXEC. It indicates that the inotify
|
||||||
|
// fd should be closed on exec(2) and friends.
|
||||||
|
IN_CLOEXEC = 0x00080000
|
||||||
|
// IN_NONBLOCK is an alias for O_NONBLOCK. It indicates I/O syscall on the
|
||||||
|
// inotify fd should not block.
|
||||||
|
IN_NONBLOCK = 0x00000800
|
||||||
|
)
|
||||||
|
|
||||||
|
// ALL_INOTIFY_BITS contains all the bits for all possible inotify events. It's
|
||||||
|
// defined in the Linux source at "include/linux/inotify.h".
|
||||||
|
const ALL_INOTIFY_BITS = IN_ACCESS | IN_MODIFY | IN_ATTRIB | IN_CLOSE_WRITE |
|
||||||
|
IN_CLOSE_NOWRITE | IN_OPEN | IN_MOVED_FROM | IN_MOVED_TO | IN_CREATE |
|
||||||
|
IN_DELETE | IN_DELETE_SELF | IN_MOVE_SELF | IN_UNMOUNT | IN_Q_OVERFLOW |
|
||||||
|
IN_IGNORED | IN_ONLYDIR | IN_DONT_FOLLOW | IN_EXCL_UNLINK | IN_MASK_ADD |
|
||||||
|
IN_ISDIR | IN_ONESHOT
|
||||||
186
pkg/abi/linux/ioctl.go
Normal file
186
pkg/abi/linux/ioctl.go
Normal file
|
|
@ -0,0 +1,186 @@
|
||||||
|
// Copyright 2018 The gVisor 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 linux
|
||||||
|
|
||||||
|
// ioctl(2) requests provided by asm-generic/ioctls.h
|
||||||
|
//
|
||||||
|
// These are ordered by request number (low byte).
|
||||||
|
const (
|
||||||
|
TCGETS = 0x00005401
|
||||||
|
TCSETS = 0x00005402
|
||||||
|
TCSETSW = 0x00005403
|
||||||
|
TCSETSF = 0x00005404
|
||||||
|
TCSBRK = 0x00005409
|
||||||
|
TIOCEXCL = 0x0000540c
|
||||||
|
TIOCNXCL = 0x0000540d
|
||||||
|
TIOCSCTTY = 0x0000540e
|
||||||
|
TIOCGPGRP = 0x0000540f
|
||||||
|
TIOCSPGRP = 0x00005410
|
||||||
|
TIOCOUTQ = 0x00005411
|
||||||
|
TIOCSTI = 0x00005412
|
||||||
|
TIOCGWINSZ = 0x00005413
|
||||||
|
TIOCSWINSZ = 0x00005414
|
||||||
|
TIOCMGET = 0x00005415
|
||||||
|
TIOCMBIS = 0x00005416
|
||||||
|
TIOCMBIC = 0x00005417
|
||||||
|
TIOCMSET = 0x00005418
|
||||||
|
TIOCINQ = 0x0000541b
|
||||||
|
FIONREAD = TIOCINQ
|
||||||
|
TIOCPKT = 0x00005420
|
||||||
|
FIONBIO = 0x00005421
|
||||||
|
TIOCSETD = 0x00005423
|
||||||
|
TIOCNOTTY = 0x00005422
|
||||||
|
TIOCGETD = 0x00005424
|
||||||
|
TCSBRKP = 0x00005425
|
||||||
|
TIOCSBRK = 0x00005427
|
||||||
|
TIOCCBRK = 0x00005428
|
||||||
|
TIOCGSID = 0x00005429
|
||||||
|
TIOCGPTN = 0x80045430
|
||||||
|
TIOCSPTLCK = 0x40045431
|
||||||
|
TIOCGDEV = 0x80045432
|
||||||
|
TIOCVHANGUP = 0x00005437
|
||||||
|
TIOCGPKT = 0x80045438
|
||||||
|
TCFLSH = 0x0000540b
|
||||||
|
TIOCCONS = 0x0000541d
|
||||||
|
TIOCSSERIAL = 0x0000541f
|
||||||
|
TIOCGEXCL = 0x80045440
|
||||||
|
TIOCGPTPEER = 0x80045441
|
||||||
|
TIOCGICOUNT = 0x0000545d
|
||||||
|
FIONCLEX = 0x00005450
|
||||||
|
FIOCLEX = 0x00005451
|
||||||
|
FIOASYNC = 0x00005452
|
||||||
|
FIOSETOWN = 0x00008901
|
||||||
|
SIOCSPGRP = 0x00008902
|
||||||
|
FIOGETOWN = 0x00008903
|
||||||
|
SIOCGPGRP = 0x00008904
|
||||||
|
)
|
||||||
|
|
||||||
|
// ioctl(2) requests provided by uapi/linux/sockios.h
|
||||||
|
const (
|
||||||
|
SIOCGIFNAME = 0x8910
|
||||||
|
SIOCGIFCONF = 0x8912
|
||||||
|
SIOCGIFFLAGS = 0x8913
|
||||||
|
SIOCGIFADDR = 0x8915
|
||||||
|
SIOCGIFDSTADDR = 0x8917
|
||||||
|
SIOCGIFBRDADDR = 0x8919
|
||||||
|
SIOCGIFNETMASK = 0x891b
|
||||||
|
SIOCGIFMETRIC = 0x891d
|
||||||
|
SIOCGIFMTU = 0x8921
|
||||||
|
SIOCGIFMEM = 0x891f
|
||||||
|
SIOCGIFHWADDR = 0x8927
|
||||||
|
SIOCGIFINDEX = 0x8933
|
||||||
|
SIOCGIFPFLAGS = 0x8935
|
||||||
|
SIOCGIFTXQLEN = 0x8942
|
||||||
|
SIOCETHTOOL = 0x8946
|
||||||
|
SIOCGMIIPHY = 0x8947
|
||||||
|
SIOCGMIIREG = 0x8948
|
||||||
|
SIOCGIFMAP = 0x8970
|
||||||
|
)
|
||||||
|
|
||||||
|
// ioctl(2) requests provided by uapi/asm-generic/sockios.h
|
||||||
|
const (
|
||||||
|
SIOCGSTAMP = 0x8906
|
||||||
|
)
|
||||||
|
|
||||||
|
// ioctl(2) directions. Used to calculate requests number.
|
||||||
|
// Constants from asm-generic/ioctl.h.
|
||||||
|
const (
|
||||||
|
IOC_NONE = 0
|
||||||
|
IOC_WRITE = 1
|
||||||
|
IOC_READ = 2
|
||||||
|
)
|
||||||
|
|
||||||
|
// Constants from asm-generic/ioctl.h.
|
||||||
|
const (
|
||||||
|
IOC_NRBITS = 8
|
||||||
|
IOC_TYPEBITS = 8
|
||||||
|
IOC_SIZEBITS = 14
|
||||||
|
IOC_DIRBITS = 2
|
||||||
|
|
||||||
|
IOC_NRSHIFT = 0
|
||||||
|
IOC_TYPESHIFT = IOC_NRSHIFT + IOC_NRBITS
|
||||||
|
IOC_SIZESHIFT = IOC_TYPESHIFT + IOC_TYPEBITS
|
||||||
|
IOC_DIRSHIFT = IOC_SIZESHIFT + IOC_SIZEBITS
|
||||||
|
)
|
||||||
|
|
||||||
|
// IOC outputs the result of _IOC macro in include/uapi/asm-generic/ioctl.h.
|
||||||
|
func IOC(dir, typ, nr, size uint32) uint32 {
|
||||||
|
return uint32(dir)<<IOC_DIRSHIFT | typ<<IOC_TYPESHIFT | nr<<IOC_NRSHIFT | size<<IOC_SIZESHIFT
|
||||||
|
}
|
||||||
|
|
||||||
|
// IO outputs the result of _IO macro in include/uapi/asm-generic/ioctl.h.
|
||||||
|
func IO(typ, nr uint32) uint32 {
|
||||||
|
return IOC(IOC_NONE, typ, nr, 0)
|
||||||
|
}
|
||||||
|
|
||||||
|
// IOR outputs the result of _IOR macro in include/uapi/asm-generic/ioctl.h.
|
||||||
|
func IOR(typ, nr, size uint32) uint32 {
|
||||||
|
return IOC(IOC_READ, typ, nr, size)
|
||||||
|
}
|
||||||
|
|
||||||
|
// IOW outputs the result of _IOW macro in include/uapi/asm-generic/ioctl.h.
|
||||||
|
func IOW(typ, nr, size uint32) uint32 {
|
||||||
|
return IOC(IOC_WRITE, typ, nr, size)
|
||||||
|
}
|
||||||
|
|
||||||
|
// IOWR outputs the result of _IOWR macro in include/uapi/asm-generic/ioctl.h.
|
||||||
|
func IOWR(typ, nr, size uint32) uint32 {
|
||||||
|
return IOC(IOC_READ|IOC_WRITE, typ, nr, size)
|
||||||
|
}
|
||||||
|
|
||||||
|
// IOC_NR outputs the result of IOC_NR macro in
|
||||||
|
// include/uapi/asm-generic/ioctl.h.
|
||||||
|
func IOC_NR(nr uint32) uint32 {
|
||||||
|
return (nr >> IOC_NRSHIFT) & ((1 << IOC_NRBITS) - 1)
|
||||||
|
}
|
||||||
|
|
||||||
|
// IOC_SIZE outputs the result of IOC_SIZE macro in
|
||||||
|
// include/uapi/asm-generic/ioctl.h.
|
||||||
|
func IOC_SIZE(nr uint32) uint32 {
|
||||||
|
return (nr >> IOC_SIZESHIFT) & ((1 << IOC_SIZEBITS) - 1)
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Used for packet mode */
|
||||||
|
const (
|
||||||
|
TIOCPKT_DATA = 0
|
||||||
|
TIOCPKT_FLUSHREAD = 1
|
||||||
|
TIOCPKT_FLUSHWRITE = 2
|
||||||
|
TIOCPKT_STOP = 4
|
||||||
|
TIOCPKT_START = 8
|
||||||
|
TIOCPKT_NOSTOP = 16
|
||||||
|
TIOCPKT_DOSTOP = 32
|
||||||
|
TIOCPKT_IOCTL = 64
|
||||||
|
)
|
||||||
|
|
||||||
|
// Kcov ioctls from include/uapi/linux/kcov.h.
|
||||||
|
var (
|
||||||
|
KCOV_INIT_TRACE = IOR('c', 1, 8)
|
||||||
|
KCOV_ENABLE = IO('c', 100)
|
||||||
|
KCOV_DISABLE = IO('c', 101)
|
||||||
|
)
|
||||||
|
|
||||||
|
// Kcov trace types from include/uapi/linux/kcov.h.
|
||||||
|
const (
|
||||||
|
KCOV_TRACE_PC = 0
|
||||||
|
KCOV_TRACE_CMP = 1
|
||||||
|
)
|
||||||
|
|
||||||
|
// Kcov state constants from include/uapi/linux/kcov.h.
|
||||||
|
const (
|
||||||
|
KCOV_MODE_DISABLED = 0
|
||||||
|
KCOV_MODE_INIT = 1
|
||||||
|
KCOV_MODE_TRACE_PC = 2
|
||||||
|
KCOV_MODE_TRACE_CMP = 3
|
||||||
|
)
|
||||||
33
pkg/abi/linux/ioctl_tun.go
Normal file
33
pkg/abi/linux/ioctl_tun.go
Normal file
|
|
@ -0,0 +1,33 @@
|
||||||
|
// Copyright 2020 The gVisor 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 linux
|
||||||
|
|
||||||
|
// ioctl(2) request numbers from linux/if_tun.h
|
||||||
|
var (
|
||||||
|
TUNSETIFF = IOW('T', 202, 4)
|
||||||
|
TUNSETPERSIST = IOW('T', 203, 4)
|
||||||
|
TUNGETIFF = IOR('T', 210, 4)
|
||||||
|
)
|
||||||
|
|
||||||
|
// Flags from net/if_tun.h
|
||||||
|
const (
|
||||||
|
IFF_TUN = 0x0001
|
||||||
|
IFF_TAP = 0x0002
|
||||||
|
IFF_NO_PI = 0x1000
|
||||||
|
IFF_NOFILTER = 0x1000
|
||||||
|
IFF_TUN_EXCL = 0x8000
|
||||||
|
// According to linux/if_tun.h "This flag has no real effect"
|
||||||
|
IFF_ONE_QUEUE = 0x2000
|
||||||
|
)
|
||||||
238
pkg/abi/linux/iouring.go
Normal file
238
pkg/abi/linux/iouring.go
Normal file
|
|
@ -0,0 +1,238 @@
|
||||||
|
// Copyright 2022 The gVisor 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 linux
|
||||||
|
|
||||||
|
// Constants for io_uring_setup(2). See include/uapi/linux/io_uring.h.
|
||||||
|
const (
|
||||||
|
IORING_SETUP_IOPOLL = (1 << 0)
|
||||||
|
IORING_SETUP_SQPOLL = (1 << 1)
|
||||||
|
IORING_SETUP_SQ_AFF = (1 << 2)
|
||||||
|
IORING_SETUP_CQSIZE = (1 << 3)
|
||||||
|
IORING_SETUP_CLAMP = (1 << 4)
|
||||||
|
IORING_SETUP_ATTACH_WQ = (1 << 5)
|
||||||
|
IORING_SETUP_R_DISABLED = (1 << 6)
|
||||||
|
IORING_SETUP_SUBMIT_ALL = (1 << 7)
|
||||||
|
)
|
||||||
|
|
||||||
|
// Constants for io_uring_enter(2). See include/uapi/linux/io_uring.h.
|
||||||
|
const (
|
||||||
|
IORING_ENTER_GETEVENTS = (1 << 0)
|
||||||
|
)
|
||||||
|
|
||||||
|
// Constants for IoUringParams.Features. See include/uapi/linux/io_uring.h.
|
||||||
|
const (
|
||||||
|
IORING_FEAT_SINGLE_MMAP = (1 << 0)
|
||||||
|
)
|
||||||
|
|
||||||
|
// Constants for IO_URING. See include/uapi/linux/io_uring.h.
|
||||||
|
const (
|
||||||
|
IORING_SETUP_COOP_TASKRUN = (1 << 8)
|
||||||
|
IORING_SETUP_TASKRUN_FLAG = (1 << 9)
|
||||||
|
IORING_SETUP_SQE128 = (1 << 10)
|
||||||
|
IORING_SETUP_CQE32 = (1 << 11)
|
||||||
|
)
|
||||||
|
|
||||||
|
// Constants for IO_URING. See io_uring/io_uring.c.
|
||||||
|
const (
|
||||||
|
IORING_MAX_ENTRIES = (1 << 15) // 32768
|
||||||
|
IORING_MAX_CQ_ENTRIES = (2 * IORING_MAX_ENTRIES)
|
||||||
|
)
|
||||||
|
|
||||||
|
// Constants for the offsets for the application to mmap the data it needs.
|
||||||
|
// See include/uapi/linux/io_uring.h.
|
||||||
|
const (
|
||||||
|
IORING_OFF_SQ_RING = 0
|
||||||
|
IORING_OFF_CQ_RING = 0x8000000
|
||||||
|
IORING_OFF_SQES = 0x10000000
|
||||||
|
)
|
||||||
|
|
||||||
|
// Constants for the IO_URING opcodes. See include/uapi/linux/io_uring.h.
|
||||||
|
const (
|
||||||
|
IORING_OP_NOP = 0
|
||||||
|
IORING_OP_READV = 1
|
||||||
|
)
|
||||||
|
|
||||||
|
// IORingIndex represents SQE array indexes.
|
||||||
|
//
|
||||||
|
// +marshal
|
||||||
|
type IORingIndex uint32
|
||||||
|
|
||||||
|
// IOSqRingOffsets implements io_sqring_offsets struct.
|
||||||
|
// IOSqRingOffsets represents offsets into IORings.
|
||||||
|
// See struct io_sqring_offsets in include/uapi/linux/io_uring.h.
|
||||||
|
//
|
||||||
|
// +marshal
|
||||||
|
type IOSqRingOffsets struct {
|
||||||
|
Head uint32 // Offset to io_rings.sq.head
|
||||||
|
Tail uint32 // Offset to io_rings.sq.tail
|
||||||
|
RingMask uint32 // Offset to io_rings.sq_ring_mask
|
||||||
|
RingEntries uint32 // Offset to io_rings.sq_ring_entries
|
||||||
|
Flags uint32 // Offset to io_rings.sq_flags
|
||||||
|
Dropped uint32 // Offset to io_rings.sq_dropped
|
||||||
|
Array uint32 // Offset to an array of SQE indices
|
||||||
|
Resv1 uint32 // Currently reserved and expected to be zero
|
||||||
|
Resv2 uint64 // Currently reserved and expected to be zero
|
||||||
|
}
|
||||||
|
|
||||||
|
// IOCqRingOffsets implements io_cqring_offsets struct.
|
||||||
|
// IOCqRingOffsets represents offsets into IORings.
|
||||||
|
// See struct io_cqring_offsets in include/uapi/linux/io_uring.h.
|
||||||
|
//
|
||||||
|
// +marshal
|
||||||
|
type IOCqRingOffsets struct {
|
||||||
|
Head uint32 // Offset to io_rings.cq.head
|
||||||
|
Tail uint32 // Offset to io_rings.cq.tail
|
||||||
|
RingMask uint32 // Offset to io_rings.cq_ring_mask
|
||||||
|
RingEntries uint32 // Offset to io_rings.cq_ring_entries
|
||||||
|
Overflow uint32 // Offset to io_rings.cq_overflow
|
||||||
|
Cqes uint32 // Offset to io_rings.cqes
|
||||||
|
Flags uint32 // Offset to io_rings.cq_flags
|
||||||
|
Resv1 uint32 // Currently reserved and expected to be zero
|
||||||
|
Resv2 uint64 // Currently reserved and expected to be zero
|
||||||
|
}
|
||||||
|
|
||||||
|
// IOUringParams implements io_uring_params struct.
|
||||||
|
// See struct io_uring_params in include/uapi/linux/io_uring.h.
|
||||||
|
//
|
||||||
|
// +marshal
|
||||||
|
type IOUringParams struct {
|
||||||
|
SqEntries uint32
|
||||||
|
CqEntries uint32
|
||||||
|
Flags uint32
|
||||||
|
SqThreadCPU uint32
|
||||||
|
SqThreadIdle uint32
|
||||||
|
Features uint32
|
||||||
|
WqFd uint32
|
||||||
|
Resv [3]uint32
|
||||||
|
SqOff IOSqRingOffsets
|
||||||
|
CqOff IOCqRingOffsets
|
||||||
|
}
|
||||||
|
|
||||||
|
// IOUringCqe implements IO completion data structure (Completion Queue Entry)
|
||||||
|
// io_uring_cqe struct. As we don't currently support IORING_SETUP_CQE32 flag
|
||||||
|
// its size is 16 bytes.
|
||||||
|
// See struct io_uring_cqe in include/uapi/linux/io_uring.h.
|
||||||
|
//
|
||||||
|
// +marshal
|
||||||
|
// +stateify savable
|
||||||
|
type IOUringCqe struct {
|
||||||
|
UserData uint64
|
||||||
|
Res int32
|
||||||
|
Flags uint32
|
||||||
|
}
|
||||||
|
|
||||||
|
// IOUring implements io_uring struct.
|
||||||
|
// See struct io_uring in io_uring/io_uring.c.
|
||||||
|
//
|
||||||
|
// +marshal
|
||||||
|
// +stateify savable
|
||||||
|
type IOUring struct {
|
||||||
|
// Both head and tail should be cacheline aligned. And we assume that
|
||||||
|
// cacheline size is 64 bytes.
|
||||||
|
Head uint32
|
||||||
|
_ [60]byte
|
||||||
|
Tail uint32
|
||||||
|
_ [60]byte
|
||||||
|
}
|
||||||
|
|
||||||
|
// IORings implements io_rings struct.
|
||||||
|
// This struct describes layout of the mapped region backed by the ringBuffersFile.
|
||||||
|
// See struct io_rings in io_uring/io_uring.c.
|
||||||
|
//
|
||||||
|
// +marshal
|
||||||
|
// +stateify savable
|
||||||
|
type IORings struct {
|
||||||
|
Sq IOUring
|
||||||
|
Cq IOUring
|
||||||
|
SqRingMask uint32
|
||||||
|
CqRingMask uint32
|
||||||
|
SqRingEntries uint32
|
||||||
|
CqRingEntries uint32
|
||||||
|
sqDropped uint32
|
||||||
|
sqFlags int32
|
||||||
|
cqFlags uint32
|
||||||
|
CqOverflow uint32
|
||||||
|
_ [32]byte // Padding so cqes is cacheline aligned
|
||||||
|
// Linux has an additional field struct io_uring_cqe cqes[], which represents
|
||||||
|
// a dynamic array. We don't include it here in order to enable marshalling.
|
||||||
|
}
|
||||||
|
|
||||||
|
// IOUringSqe implements io_uring_sqe struct.
|
||||||
|
// This struct represents IO submission data structure (Submission Queue Entry). As we don't yet
|
||||||
|
// support IORING_SETUP_SQE128 flag, its size is 64 bytes with no extra padding at the end.
|
||||||
|
// See include/uapi/linux/io_uring.h.
|
||||||
|
//
|
||||||
|
// +marshal
|
||||||
|
// +stateify savable
|
||||||
|
type IOUringSqe struct {
|
||||||
|
Opcode uint8
|
||||||
|
Flags uint8
|
||||||
|
IoPrio uint16
|
||||||
|
Fd int32
|
||||||
|
OffOrAddrOrCmdOp uint64
|
||||||
|
AddrOrSpliceOff uint64
|
||||||
|
Len uint32
|
||||||
|
specialFlags uint32
|
||||||
|
UserData uint64
|
||||||
|
BufIndexOrGroup uint16
|
||||||
|
personality uint16
|
||||||
|
spliceFDOrFileIndex int32
|
||||||
|
addr3 uint64
|
||||||
|
_ uint64
|
||||||
|
}
|
||||||
|
|
||||||
|
const (
|
||||||
|
_IOSqRingOffset = 0 // +checkoffset . IORings.Sq
|
||||||
|
_IOSqRingOffsetHead = 0 // +checkoffset . IOUring.Head
|
||||||
|
_IOSqRingOffsetTail = 64 // +checkoffset . IOUring.Tail
|
||||||
|
_IOSqRingOffsetMask = 256 // +checkoffset . IORings.SqRingMask
|
||||||
|
_IOSqRingOffsetEntries = 264 // +checkoffset . IORings.SqRingEntries
|
||||||
|
_IOSqRingOffsetFlags = 276 // +checkoffset . IORings.sqFlags
|
||||||
|
_IOSqRingOffsetDropped = 272 // +checkoffset . IORings.sqDropped
|
||||||
|
)
|
||||||
|
|
||||||
|
// PreComputedIOSqRingOffsets returns precomputed values for IOSqRingOffsets.
|
||||||
|
func PreComputedIOSqRingOffsets() IOSqRingOffsets {
|
||||||
|
return IOSqRingOffsets{
|
||||||
|
Head: _IOSqRingOffset + _IOSqRingOffsetHead,
|
||||||
|
Tail: _IOSqRingOffset + _IOSqRingOffsetTail,
|
||||||
|
RingMask: _IOSqRingOffsetMask,
|
||||||
|
RingEntries: _IOSqRingOffsetEntries,
|
||||||
|
Flags: _IOSqRingOffsetFlags,
|
||||||
|
Dropped: _IOSqRingOffsetDropped,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const (
|
||||||
|
_IOCqRingOffset = 128 // +checkoffset . IORings.Cq
|
||||||
|
_IOCqRingOffsetHead = 0 // +checkoffset . IOUring.Head
|
||||||
|
_IOCqRingOffsetTail = 64 // +checkoffset . IOUring.Tail
|
||||||
|
_IOCqRingOffsetMask = 260 // +checkoffset . IORings.CqRingMask
|
||||||
|
_IOCqRingOffsetEntries = 268 // +checkoffset . IORings.CqRingEntries
|
||||||
|
_IOCqRingOffsetFlags = 280 // +checkoffset . IORings.cqFlags
|
||||||
|
_IOCqRingOffsetOverflow = 284 // +checkoffset . IORings.CqOverflow
|
||||||
|
)
|
||||||
|
|
||||||
|
// PreComputedIOCqRingOffsets returns precomputed values for IOCqRingOffsets.
|
||||||
|
func PreComputedIOCqRingOffsets() IOCqRingOffsets {
|
||||||
|
return IOCqRingOffsets{
|
||||||
|
Head: _IOCqRingOffset + _IOCqRingOffsetHead,
|
||||||
|
Tail: _IOCqRingOffset + _IOCqRingOffsetTail,
|
||||||
|
RingMask: _IOCqRingOffsetMask,
|
||||||
|
RingEntries: _IOCqRingOffsetEntries,
|
||||||
|
Overflow: _IOCqRingOffsetOverflow,
|
||||||
|
Flags: _IOCqRingOffsetFlags,
|
||||||
|
}
|
||||||
|
}
|
||||||
171
pkg/abi/linux/ip.go
Normal file
171
pkg/abi/linux/ip.go
Normal file
|
|
@ -0,0 +1,171 @@
|
||||||
|
// Copyright 2018 The gVisor 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 linux
|
||||||
|
|
||||||
|
// IP protocols
|
||||||
|
const (
|
||||||
|
IPPROTO_IP = 0
|
||||||
|
IPPROTO_ICMP = 1
|
||||||
|
IPPROTO_IGMP = 2
|
||||||
|
IPPROTO_IPIP = 4
|
||||||
|
IPPROTO_TCP = 6
|
||||||
|
IPPROTO_EGP = 8
|
||||||
|
IPPROTO_PUP = 12
|
||||||
|
IPPROTO_UDP = 17
|
||||||
|
IPPROTO_IDP = 22
|
||||||
|
IPPROTO_TP = 29
|
||||||
|
IPPROTO_DCCP = 33
|
||||||
|
IPPROTO_IPV6 = 41
|
||||||
|
IPPROTO_RSVP = 46
|
||||||
|
IPPROTO_GRE = 47
|
||||||
|
IPPROTO_ESP = 50
|
||||||
|
IPPROTO_AH = 51
|
||||||
|
IPPROTO_ICMPV6 = 58
|
||||||
|
IPPROTO_MTP = 92
|
||||||
|
IPPROTO_BEETPH = 94
|
||||||
|
IPPROTO_ENCAP = 98
|
||||||
|
IPPROTO_PIM = 103
|
||||||
|
IPPROTO_COMP = 108
|
||||||
|
IPPROTO_SCTP = 132
|
||||||
|
IPPROTO_UDPLITE = 136
|
||||||
|
IPPROTO_MPLS = 137
|
||||||
|
IPPROTO_RAW = 255
|
||||||
|
)
|
||||||
|
|
||||||
|
// Socket options from uapi/linux/in.h
|
||||||
|
const (
|
||||||
|
IP_TOS = 1
|
||||||
|
IP_TTL = 2
|
||||||
|
IP_HDRINCL = 3
|
||||||
|
IP_OPTIONS = 4
|
||||||
|
IP_ROUTER_ALERT = 5
|
||||||
|
IP_RECVOPTS = 6
|
||||||
|
IP_RETOPTS = 7
|
||||||
|
IP_PKTINFO = 8
|
||||||
|
IP_PKTOPTIONS = 9
|
||||||
|
IP_MTU_DISCOVER = 10
|
||||||
|
IP_RECVERR = 11
|
||||||
|
IP_RECVTTL = 12
|
||||||
|
IP_RECVTOS = 13
|
||||||
|
IP_MTU = 14
|
||||||
|
IP_FREEBIND = 15
|
||||||
|
IP_IPSEC_POLICY = 16
|
||||||
|
IP_XFRM_POLICY = 17
|
||||||
|
IP_PASSSEC = 18
|
||||||
|
IP_TRANSPARENT = 19
|
||||||
|
IP_ORIGDSTADDR = 20
|
||||||
|
IP_RECVORIGDSTADDR = IP_ORIGDSTADDR
|
||||||
|
IP_MINTTL = 21
|
||||||
|
IP_NODEFRAG = 22
|
||||||
|
IP_CHECKSUM = 23
|
||||||
|
IP_BIND_ADDRESS_NO_PORT = 24
|
||||||
|
IP_RECVFRAGSIZE = 25
|
||||||
|
IP_RECVERR_RFC4884 = 26
|
||||||
|
IP_MULTICAST_IF = 32
|
||||||
|
IP_MULTICAST_TTL = 33
|
||||||
|
IP_MULTICAST_LOOP = 34
|
||||||
|
IP_ADD_MEMBERSHIP = 35
|
||||||
|
IP_DROP_MEMBERSHIP = 36
|
||||||
|
IP_UNBLOCK_SOURCE = 37
|
||||||
|
IP_BLOCK_SOURCE = 38
|
||||||
|
IP_ADD_SOURCE_MEMBERSHIP = 39
|
||||||
|
IP_DROP_SOURCE_MEMBERSHIP = 40
|
||||||
|
IP_MSFILTER = 41
|
||||||
|
MCAST_JOIN_GROUP = 42
|
||||||
|
MCAST_BLOCK_SOURCE = 43
|
||||||
|
MCAST_UNBLOCK_SOURCE = 44
|
||||||
|
MCAST_LEAVE_GROUP = 45
|
||||||
|
MCAST_JOIN_SOURCE_GROUP = 46
|
||||||
|
MCAST_LEAVE_SOURCE_GROUP = 47
|
||||||
|
MCAST_MSFILTER = 48
|
||||||
|
IP_MULTICAST_ALL = 49
|
||||||
|
IP_UNICAST_IF = 50
|
||||||
|
IP_LOCAL_PORT_RANGE = 51
|
||||||
|
)
|
||||||
|
|
||||||
|
// IP_MTU_DISCOVER values from uapi/linux/in.h
|
||||||
|
const (
|
||||||
|
IP_PMTUDISC_DONT = 0
|
||||||
|
IP_PMTUDISC_WANT = 1
|
||||||
|
IP_PMTUDISC_DO = 2
|
||||||
|
IP_PMTUDISC_PROBE = 3
|
||||||
|
IP_PMTUDISC_INTERFACE = 4
|
||||||
|
IP_PMTUDISC_OMIT = 5
|
||||||
|
)
|
||||||
|
|
||||||
|
// Socket options from uapi/linux/in6.h
|
||||||
|
const (
|
||||||
|
IPV6_ADDRFORM = 1
|
||||||
|
IPV6_2292PKTINFO = 2
|
||||||
|
IPV6_2292HOPOPTS = 3
|
||||||
|
IPV6_2292DSTOPTS = 4
|
||||||
|
IPV6_2292RTHDR = 5
|
||||||
|
IPV6_2292PKTOPTIONS = 6
|
||||||
|
IPV6_CHECKSUM = 7
|
||||||
|
IPV6_2292HOPLIMIT = 8
|
||||||
|
IPV6_NEXTHOP = 9
|
||||||
|
IPV6_FLOWINFO = 11
|
||||||
|
IPV6_UNICAST_HOPS = 16
|
||||||
|
IPV6_MULTICAST_IF = 17
|
||||||
|
IPV6_MULTICAST_HOPS = 18
|
||||||
|
IPV6_MULTICAST_LOOP = 19
|
||||||
|
IPV6_ADD_MEMBERSHIP = 20
|
||||||
|
IPV6_DROP_MEMBERSHIP = 21
|
||||||
|
IPV6_ROUTER_ALERT = 22
|
||||||
|
IPV6_MTU_DISCOVER = 23
|
||||||
|
IPV6_MTU = 24
|
||||||
|
IPV6_RECVERR = 25
|
||||||
|
IPV6_V6ONLY = 26
|
||||||
|
IPV6_JOIN_ANYCAST = 27
|
||||||
|
IPV6_LEAVE_ANYCAST = 28
|
||||||
|
IPV6_MULTICAST_ALL = 29
|
||||||
|
IPV6_ROUTER_ALERT_ISOLATE = 30
|
||||||
|
IPV6_RECVERR_RFC4884 = 31
|
||||||
|
IPV6_FLOWLABEL_MGR = 32
|
||||||
|
IPV6_FLOWINFO_SEND = 33
|
||||||
|
IPV6_IPSEC_POLICY = 34
|
||||||
|
IPV6_XFRM_POLICY = 35
|
||||||
|
IPV6_HDRINCL = 36
|
||||||
|
IPV6_RECVPKTINFO = 49
|
||||||
|
IPV6_PKTINFO = 50
|
||||||
|
IPV6_RECVHOPLIMIT = 51
|
||||||
|
IPV6_HOPLIMIT = 52
|
||||||
|
IPV6_RECVHOPOPTS = 53
|
||||||
|
IPV6_HOPOPTS = 54
|
||||||
|
IPV6_RTHDRDSTOPTS = 55
|
||||||
|
IPV6_RECVRTHDR = 56
|
||||||
|
IPV6_RTHDR = 57
|
||||||
|
IPV6_RECVDSTOPTS = 58
|
||||||
|
IPV6_DSTOPTS = 59
|
||||||
|
IPV6_RECVPATHMTU = 60
|
||||||
|
IPV6_PATHMTU = 61
|
||||||
|
IPV6_DONTFRAG = 62
|
||||||
|
IPV6_RECVTCLASS = 66
|
||||||
|
IPV6_TCLASS = 67
|
||||||
|
IPV6_AUTOFLOWLABEL = 70
|
||||||
|
IPV6_ADDR_PREFERENCES = 72
|
||||||
|
IPV6_MINHOPCOUNT = 73
|
||||||
|
IPV6_ORIGDSTADDR = 74
|
||||||
|
IPV6_RECVORIGDSTADDR = IPV6_ORIGDSTADDR
|
||||||
|
IPV6_TRANSPARENT = 75
|
||||||
|
IPV6_UNICAST_IF = 76
|
||||||
|
IPV6_RECVFRAGSIZE = 77
|
||||||
|
IPV6_FREEBIND = 78
|
||||||
|
)
|
||||||
|
|
||||||
|
// Socket options from uapi/linux/icmpv6.h
|
||||||
|
const (
|
||||||
|
ICMPV6_FILTER = 1
|
||||||
|
)
|
||||||
61
pkg/abi/linux/ipc.go
Normal file
61
pkg/abi/linux/ipc.go
Normal file
|
|
@ -0,0 +1,61 @@
|
||||||
|
// Copyright 2018 The gVisor 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 linux
|
||||||
|
|
||||||
|
// Control commands used with semctl, shmctl, and msgctl.
|
||||||
|
//
|
||||||
|
// Source: include/uapi/linux/ipc.h.
|
||||||
|
const (
|
||||||
|
IPC_RMID = 0
|
||||||
|
IPC_SET = 1
|
||||||
|
IPC_STAT = 2
|
||||||
|
IPC_INFO = 3
|
||||||
|
)
|
||||||
|
|
||||||
|
// Resource get request flags.
|
||||||
|
//
|
||||||
|
// Source: include/uapi/linux/ipc.h
|
||||||
|
const (
|
||||||
|
IPC_CREAT = 0o0001000
|
||||||
|
IPC_EXCL = 0o0002000
|
||||||
|
IPC_NOWAIT = 0o0004000
|
||||||
|
)
|
||||||
|
|
||||||
|
// IPC flags.
|
||||||
|
const (
|
||||||
|
IPC_PRIVATE = 0
|
||||||
|
)
|
||||||
|
|
||||||
|
// In Linux, amd64 does not enable CONFIG_ARCH_WANT_IPC_PARSE_VERSION, so SysV
|
||||||
|
// IPC unconditionally uses the "new" 64-bit structures that are needed for
|
||||||
|
// features like 32-bit UIDs.
|
||||||
|
|
||||||
|
// IPCPerm is equivalent to struct ipc64_perm.
|
||||||
|
//
|
||||||
|
// +marshal
|
||||||
|
type IPCPerm struct {
|
||||||
|
Key uint32
|
||||||
|
UID uint32
|
||||||
|
GID uint32
|
||||||
|
CUID uint32
|
||||||
|
CGID uint32
|
||||||
|
Mode uint16
|
||||||
|
_ uint16
|
||||||
|
Seq uint16
|
||||||
|
_ uint16
|
||||||
|
_ uint32
|
||||||
|
unused1 uint64
|
||||||
|
unused2 uint64
|
||||||
|
}
|
||||||
29
pkg/abi/linux/keyctl.go
Normal file
29
pkg/abi/linux/keyctl.go
Normal file
|
|
@ -0,0 +1,29 @@
|
||||||
|
// Copyright 2023 The gVisor 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 linux
|
||||||
|
|
||||||
|
// Constants used by keyctl(2) and other keyrings-related syscalls.
|
||||||
|
// Source: include/uapi/linux/keyctl.h
|
||||||
|
|
||||||
|
const (
|
||||||
|
KEY_SPEC_SESSION_KEYRING = -3
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
KEYCTL_GET_KEYRING_ID = 0
|
||||||
|
KEYCTL_JOIN_SESSION_KEYRING = 1
|
||||||
|
KEYCTL_SETPERM = 5
|
||||||
|
KEYCTL_DESCRIBE = 6
|
||||||
|
)
|
||||||
88
pkg/abi/linux/limits.go
Normal file
88
pkg/abi/linux/limits.go
Normal file
|
|
@ -0,0 +1,88 @@
|
||||||
|
// Copyright 2018 The gVisor 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 linux
|
||||||
|
|
||||||
|
// Resources for getrlimit(2)/setrlimit(2)/prlimit(2).
|
||||||
|
const (
|
||||||
|
RLIMIT_CPU = 0
|
||||||
|
RLIMIT_FSIZE = 1
|
||||||
|
RLIMIT_DATA = 2
|
||||||
|
RLIMIT_STACK = 3
|
||||||
|
RLIMIT_CORE = 4
|
||||||
|
RLIMIT_RSS = 5
|
||||||
|
RLIMIT_NPROC = 6
|
||||||
|
RLIMIT_NOFILE = 7
|
||||||
|
RLIMIT_MEMLOCK = 8
|
||||||
|
RLIMIT_AS = 9
|
||||||
|
RLIMIT_LOCKS = 10
|
||||||
|
RLIMIT_SIGPENDING = 11
|
||||||
|
RLIMIT_MSGQUEUE = 12
|
||||||
|
RLIMIT_NICE = 13
|
||||||
|
RLIMIT_RTPRIO = 14
|
||||||
|
RLIMIT_RTTIME = 15
|
||||||
|
)
|
||||||
|
|
||||||
|
// RLimit corresponds to Linux's struct rlimit.
|
||||||
|
type RLimit struct {
|
||||||
|
// Cur specifies the soft limit.
|
||||||
|
Cur uint64
|
||||||
|
// Max specifies the hard limit.
|
||||||
|
Max uint64
|
||||||
|
}
|
||||||
|
|
||||||
|
const (
|
||||||
|
// RLimInfinity is RLIM_INFINITY on Linux.
|
||||||
|
RLimInfinity = ^uint64(0)
|
||||||
|
|
||||||
|
// DefaultStackSoftLimit is called _STK_LIM in Linux.
|
||||||
|
DefaultStackSoftLimit = 8 * 1024 * 1024
|
||||||
|
|
||||||
|
// DefaultNprocLimit is defined in kernel/fork.c:set_max_threads, and
|
||||||
|
// called MAX_THREADS / 2 in Linux.
|
||||||
|
DefaultNprocLimit = FUTEX_TID_MASK / 2
|
||||||
|
|
||||||
|
// DefaultNofileSoftLimit is called INR_OPEN_CUR in Linux.
|
||||||
|
DefaultNofileSoftLimit = 1024
|
||||||
|
|
||||||
|
// DefaultNofileHardLimit is called INR_OPEN_MAX in Linux.
|
||||||
|
DefaultNofileHardLimit = 4096
|
||||||
|
|
||||||
|
// DefaultMemlockLimit is called MLOCK_LIMIT in Linux.
|
||||||
|
DefaultMemlockLimit = 64 * 1024
|
||||||
|
|
||||||
|
// DefaultMsgqueueLimit is called MQ_BYTES_MAX in Linux.
|
||||||
|
DefaultMsgqueueLimit = 819200
|
||||||
|
)
|
||||||
|
|
||||||
|
// InitRLimits is a map of initial rlimits set by Linux in
|
||||||
|
// include/asm-generic/resource.h.
|
||||||
|
var InitRLimits = map[int]RLimit{
|
||||||
|
RLIMIT_CPU: {RLimInfinity, RLimInfinity},
|
||||||
|
RLIMIT_FSIZE: {RLimInfinity, RLimInfinity},
|
||||||
|
RLIMIT_DATA: {RLimInfinity, RLimInfinity},
|
||||||
|
RLIMIT_STACK: {DefaultStackSoftLimit, RLimInfinity},
|
||||||
|
RLIMIT_CORE: {0, RLimInfinity},
|
||||||
|
RLIMIT_RSS: {RLimInfinity, RLimInfinity},
|
||||||
|
RLIMIT_NPROC: {DefaultNprocLimit, DefaultNprocLimit},
|
||||||
|
RLIMIT_NOFILE: {DefaultNofileSoftLimit, DefaultNofileHardLimit},
|
||||||
|
RLIMIT_MEMLOCK: {DefaultMemlockLimit, DefaultMemlockLimit},
|
||||||
|
RLIMIT_AS: {RLimInfinity, RLimInfinity},
|
||||||
|
RLIMIT_LOCKS: {RLimInfinity, RLimInfinity},
|
||||||
|
RLIMIT_SIGPENDING: {0, 0},
|
||||||
|
RLIMIT_MSGQUEUE: {DefaultMsgqueueLimit, DefaultMsgqueueLimit},
|
||||||
|
RLIMIT_NICE: {0, 0},
|
||||||
|
RLIMIT_RTPRIO: {0, 0},
|
||||||
|
RLIMIT_RTTIME: {RLimInfinity, RLimInfinity},
|
||||||
|
}
|
||||||
42
pkg/abi/linux/linux.go
Normal file
42
pkg/abi/linux/linux.go
Normal file
|
|
@ -0,0 +1,42 @@
|
||||||
|
// Copyright 2018 The gVisor 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 linux contains the constants and types needed to interface with a
|
||||||
|
// Linux kernel.
|
||||||
|
package linux
|
||||||
|
|
||||||
|
// NumSoftIRQ is the number of software IRQs, exposed via /proc/stat.
|
||||||
|
//
|
||||||
|
// Defined in linux/interrupt.h.
|
||||||
|
const NumSoftIRQ = 10
|
||||||
|
|
||||||
|
// Sysinfo is the structure provided by sysinfo on linux versions > 2.3.48.
|
||||||
|
//
|
||||||
|
// +marshal
|
||||||
|
type Sysinfo struct {
|
||||||
|
Uptime int64
|
||||||
|
Loads [3]uint64
|
||||||
|
TotalRAM uint64
|
||||||
|
FreeRAM uint64
|
||||||
|
SharedRAM uint64
|
||||||
|
BufferRAM uint64
|
||||||
|
TotalSwap uint64
|
||||||
|
FreeSwap uint64
|
||||||
|
Procs uint16
|
||||||
|
_ [6]byte // Pad Procs to 64bits.
|
||||||
|
TotalHigh uint64
|
||||||
|
FreeHigh uint64
|
||||||
|
Unit uint32 `marshal:"unaligned"` // Struct ends mid-64-bit-word.
|
||||||
|
// The _f field in the glibc version of Sysinfo has size 0 on AMD64.
|
||||||
|
}
|
||||||
22507
pkg/abi/linux/linux_abi_autogen_unsafe.go
Normal file
22507
pkg/abi/linux/linux_abi_autogen_unsafe.go
Normal file
File diff suppressed because it is too large
Load diff
760
pkg/abi/linux/linux_amd64_abi_autogen_unsafe.go
Normal file
760
pkg/abi/linux/linux_amd64_abi_autogen_unsafe.go
Normal file
|
|
@ -0,0 +1,760 @@
|
||||||
|
// Automatically generated marshal implementation. See tools/go_marshal.
|
||||||
|
|
||||||
|
// If there are issues with build constraint aggregation, see
|
||||||
|
// tools/go_marshal/gomarshal/generator.go:writeHeader(). The constraints here
|
||||||
|
// come from the input set of files used to generate this file. This input set
|
||||||
|
// is filtered based on pre-defined file suffixes related to build constraints,
|
||||||
|
// see tools/defs.bzl:calculate_sets().
|
||||||
|
|
||||||
|
//go:build amd64 && amd64 && amd64 && amd64 && amd64 && amd64
|
||||||
|
// +build amd64,amd64,amd64,amd64,amd64,amd64
|
||||||
|
|
||||||
|
package linux
|
||||||
|
|
||||||
|
import (
|
||||||
|
"io"
|
||||||
|
"reflect"
|
||||||
|
"runtime"
|
||||||
|
"unsafe"
|
||||||
|
|
||||||
|
"github.com/sagernet/gvisor/pkg/gohacks"
|
||||||
|
"github.com/sagernet/gvisor/pkg/hostarch"
|
||||||
|
"github.com/sagernet/gvisor/pkg/marshal"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Marshallable types used by this file.
|
||||||
|
var (
|
||||||
|
_ marshal.Marshallable = (*EpollEvent)(nil)
|
||||||
|
_ marshal.Marshallable = (*IPCPerm)(nil)
|
||||||
|
_ marshal.Marshallable = (*PtraceRegs)(nil)
|
||||||
|
_ marshal.Marshallable = (*SemidDS)(nil)
|
||||||
|
_ marshal.Marshallable = (*Stat)(nil)
|
||||||
|
_ marshal.Marshallable = (*TimeT)(nil)
|
||||||
|
_ marshal.Marshallable = (*Timespec)(nil)
|
||||||
|
)
|
||||||
|
|
||||||
|
// SizeBytes implements marshal.Marshallable.SizeBytes.
|
||||||
|
func (e *EpollEvent) SizeBytes() int {
|
||||||
|
return 4 +
|
||||||
|
4*2
|
||||||
|
}
|
||||||
|
|
||||||
|
// MarshalBytes implements marshal.Marshallable.MarshalBytes.
|
||||||
|
func (e *EpollEvent) MarshalBytes(dst []byte) []byte {
|
||||||
|
hostarch.ByteOrder.PutUint32(dst[:4], uint32(e.Events))
|
||||||
|
dst = dst[4:]
|
||||||
|
for idx := 0; idx < 2; idx++ {
|
||||||
|
hostarch.ByteOrder.PutUint32(dst[:4], uint32(e.Data[idx]))
|
||||||
|
dst = dst[4:]
|
||||||
|
}
|
||||||
|
return dst
|
||||||
|
}
|
||||||
|
|
||||||
|
// UnmarshalBytes implements marshal.Marshallable.UnmarshalBytes.
|
||||||
|
func (e *EpollEvent) UnmarshalBytes(src []byte) []byte {
|
||||||
|
e.Events = uint32(hostarch.ByteOrder.Uint32(src[:4]))
|
||||||
|
src = src[4:]
|
||||||
|
for idx := 0; idx < 2; idx++ {
|
||||||
|
e.Data[idx] = int32(hostarch.ByteOrder.Uint32(src[:4]))
|
||||||
|
src = src[4:]
|
||||||
|
}
|
||||||
|
return src
|
||||||
|
}
|
||||||
|
|
||||||
|
// Packed implements marshal.Marshallable.Packed.
|
||||||
|
//
|
||||||
|
//go:nosplit
|
||||||
|
func (e *EpollEvent) Packed() bool {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
// MarshalUnsafe implements marshal.Marshallable.MarshalUnsafe.
|
||||||
|
func (e *EpollEvent) MarshalUnsafe(dst []byte) []byte {
|
||||||
|
size := e.SizeBytes()
|
||||||
|
gohacks.Memmove(unsafe.Pointer(&dst[0]), unsafe.Pointer(e), uintptr(size))
|
||||||
|
return dst[size:]
|
||||||
|
}
|
||||||
|
|
||||||
|
// UnmarshalUnsafe implements marshal.Marshallable.UnmarshalUnsafe.
|
||||||
|
func (e *EpollEvent) UnmarshalUnsafe(src []byte) []byte {
|
||||||
|
size := e.SizeBytes()
|
||||||
|
gohacks.Memmove(unsafe.Pointer(e), unsafe.Pointer(&src[0]), uintptr(size))
|
||||||
|
return src[size:]
|
||||||
|
}
|
||||||
|
|
||||||
|
// CopyOutN implements marshal.Marshallable.CopyOutN.
|
||||||
|
func (e *EpollEvent) CopyOutN(cc marshal.CopyContext, addr hostarch.Addr, limit int) (int, error) {
|
||||||
|
// Construct a slice backed by dst's underlying memory.
|
||||||
|
var buf []byte
|
||||||
|
hdr := (*reflect.SliceHeader)(unsafe.Pointer(&buf))
|
||||||
|
hdr.Data = uintptr(gohacks.Noescape(unsafe.Pointer(e)))
|
||||||
|
hdr.Len = e.SizeBytes()
|
||||||
|
hdr.Cap = e.SizeBytes()
|
||||||
|
|
||||||
|
length, err := cc.CopyOutBytes(addr, buf[:limit]) // escapes: okay.
|
||||||
|
// Since we bypassed the compiler's escape analysis, indicate that e
|
||||||
|
// must live until the use above.
|
||||||
|
runtime.KeepAlive(e) // escapes: replaced by intrinsic.
|
||||||
|
return length, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// CopyOut implements marshal.Marshallable.CopyOut.
|
||||||
|
func (e *EpollEvent) CopyOut(cc marshal.CopyContext, addr hostarch.Addr) (int, error) {
|
||||||
|
return e.CopyOutN(cc, addr, e.SizeBytes())
|
||||||
|
}
|
||||||
|
|
||||||
|
// CopyInN implements marshal.Marshallable.CopyInN.
|
||||||
|
func (e *EpollEvent) CopyInN(cc marshal.CopyContext, addr hostarch.Addr, limit int) (int, error) {
|
||||||
|
// Construct a slice backed by dst's underlying memory.
|
||||||
|
var buf []byte
|
||||||
|
hdr := (*reflect.SliceHeader)(unsafe.Pointer(&buf))
|
||||||
|
hdr.Data = uintptr(gohacks.Noescape(unsafe.Pointer(e)))
|
||||||
|
hdr.Len = e.SizeBytes()
|
||||||
|
hdr.Cap = e.SizeBytes()
|
||||||
|
|
||||||
|
length, err := cc.CopyInBytes(addr, buf[:limit]) // escapes: okay.
|
||||||
|
// Since we bypassed the compiler's escape analysis, indicate that e
|
||||||
|
// must live until the use above.
|
||||||
|
runtime.KeepAlive(e) // escapes: replaced by intrinsic.
|
||||||
|
return length, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// CopyIn implements marshal.Marshallable.CopyIn.
|
||||||
|
func (e *EpollEvent) CopyIn(cc marshal.CopyContext, addr hostarch.Addr) (int, error) {
|
||||||
|
return e.CopyInN(cc, addr, e.SizeBytes())
|
||||||
|
}
|
||||||
|
|
||||||
|
// WriteTo implements io.WriterTo.WriteTo.
|
||||||
|
func (e *EpollEvent) WriteTo(writer io.Writer) (int64, error) {
|
||||||
|
// Construct a slice backed by dst's underlying memory.
|
||||||
|
var buf []byte
|
||||||
|
hdr := (*reflect.SliceHeader)(unsafe.Pointer(&buf))
|
||||||
|
hdr.Data = uintptr(gohacks.Noescape(unsafe.Pointer(e)))
|
||||||
|
hdr.Len = e.SizeBytes()
|
||||||
|
hdr.Cap = e.SizeBytes()
|
||||||
|
|
||||||
|
length, err := writer.Write(buf)
|
||||||
|
// Since we bypassed the compiler's escape analysis, indicate that e
|
||||||
|
// must live until the use above.
|
||||||
|
runtime.KeepAlive(e) // escapes: replaced by intrinsic.
|
||||||
|
return int64(length), err
|
||||||
|
}
|
||||||
|
|
||||||
|
// CopyEpollEventSliceIn copies in a slice of EpollEvent objects from the task's memory.
|
||||||
|
func CopyEpollEventSliceIn(cc marshal.CopyContext, addr hostarch.Addr, dst []EpollEvent) (int, error) {
|
||||||
|
count := len(dst)
|
||||||
|
if count == 0 {
|
||||||
|
return 0, nil
|
||||||
|
}
|
||||||
|
size := (*EpollEvent)(nil).SizeBytes()
|
||||||
|
|
||||||
|
ptr := unsafe.Pointer(&dst)
|
||||||
|
val := gohacks.Noescape(unsafe.Pointer((*reflect.SliceHeader)(ptr).Data))
|
||||||
|
|
||||||
|
// Construct a slice backed by dst's underlying memory.
|
||||||
|
var buf []byte
|
||||||
|
hdr := (*reflect.SliceHeader)(unsafe.Pointer(&buf))
|
||||||
|
hdr.Data = uintptr(val)
|
||||||
|
hdr.Len = size * count
|
||||||
|
hdr.Cap = size * count
|
||||||
|
|
||||||
|
length, err := cc.CopyInBytes(addr, buf)
|
||||||
|
// Since we bypassed the compiler's escape analysis, indicate that dst
|
||||||
|
// must live until the use above.
|
||||||
|
runtime.KeepAlive(dst) // escapes: replaced by intrinsic.
|
||||||
|
return length, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// CopyEpollEventSliceOut copies a slice of EpollEvent objects to the task's memory.
|
||||||
|
func CopyEpollEventSliceOut(cc marshal.CopyContext, addr hostarch.Addr, src []EpollEvent) (int, error) {
|
||||||
|
count := len(src)
|
||||||
|
if count == 0 {
|
||||||
|
return 0, nil
|
||||||
|
}
|
||||||
|
size := (*EpollEvent)(nil).SizeBytes()
|
||||||
|
|
||||||
|
ptr := unsafe.Pointer(&src)
|
||||||
|
val := gohacks.Noescape(unsafe.Pointer((*reflect.SliceHeader)(ptr).Data))
|
||||||
|
|
||||||
|
// Construct a slice backed by dst's underlying memory.
|
||||||
|
var buf []byte
|
||||||
|
hdr := (*reflect.SliceHeader)(unsafe.Pointer(&buf))
|
||||||
|
hdr.Data = uintptr(val)
|
||||||
|
hdr.Len = size * count
|
||||||
|
hdr.Cap = size * count
|
||||||
|
|
||||||
|
length, err := cc.CopyOutBytes(addr, buf)
|
||||||
|
// Since we bypassed the compiler's escape analysis, indicate that src
|
||||||
|
// must live until the use above.
|
||||||
|
runtime.KeepAlive(src) // escapes: replaced by intrinsic.
|
||||||
|
return length, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// MarshalUnsafeEpollEventSlice is like EpollEvent.MarshalUnsafe, but for a []EpollEvent.
|
||||||
|
func MarshalUnsafeEpollEventSlice(src []EpollEvent, dst []byte) []byte {
|
||||||
|
count := len(src)
|
||||||
|
if count == 0 {
|
||||||
|
return dst
|
||||||
|
}
|
||||||
|
|
||||||
|
size := (*EpollEvent)(nil).SizeBytes()
|
||||||
|
buf := dst[:size*count]
|
||||||
|
gohacks.Memmove(unsafe.Pointer(&buf[0]), unsafe.Pointer(&src[0]), uintptr(len(buf)))
|
||||||
|
return dst[size*count:]
|
||||||
|
}
|
||||||
|
|
||||||
|
// UnmarshalUnsafeEpollEventSlice is like EpollEvent.UnmarshalUnsafe, but for a []EpollEvent.
|
||||||
|
func UnmarshalUnsafeEpollEventSlice(dst []EpollEvent, src []byte) []byte {
|
||||||
|
count := len(dst)
|
||||||
|
if count == 0 {
|
||||||
|
return src
|
||||||
|
}
|
||||||
|
|
||||||
|
size := (*EpollEvent)(nil).SizeBytes()
|
||||||
|
buf := src[:size*count]
|
||||||
|
gohacks.Memmove(unsafe.Pointer(&dst[0]), unsafe.Pointer(&buf[0]), uintptr(len(buf)))
|
||||||
|
return src[size*count:]
|
||||||
|
}
|
||||||
|
|
||||||
|
// SizeBytes implements marshal.Marshallable.SizeBytes.
|
||||||
|
func (s *Stat) SizeBytes() int {
|
||||||
|
return 72 +
|
||||||
|
(*Timespec)(nil).SizeBytes() +
|
||||||
|
(*Timespec)(nil).SizeBytes() +
|
||||||
|
(*Timespec)(nil).SizeBytes() +
|
||||||
|
8*3
|
||||||
|
}
|
||||||
|
|
||||||
|
// MarshalBytes implements marshal.Marshallable.MarshalBytes.
|
||||||
|
func (s *Stat) MarshalBytes(dst []byte) []byte {
|
||||||
|
hostarch.ByteOrder.PutUint64(dst[:8], uint64(s.Dev))
|
||||||
|
dst = dst[8:]
|
||||||
|
hostarch.ByteOrder.PutUint64(dst[:8], uint64(s.Ino))
|
||||||
|
dst = dst[8:]
|
||||||
|
hostarch.ByteOrder.PutUint64(dst[:8], uint64(s.Nlink))
|
||||||
|
dst = dst[8:]
|
||||||
|
hostarch.ByteOrder.PutUint32(dst[:4], uint32(s.Mode))
|
||||||
|
dst = dst[4:]
|
||||||
|
hostarch.ByteOrder.PutUint32(dst[:4], uint32(s.UID))
|
||||||
|
dst = dst[4:]
|
||||||
|
hostarch.ByteOrder.PutUint32(dst[:4], uint32(s.GID))
|
||||||
|
dst = dst[4:]
|
||||||
|
// Padding: dst[:sizeof(int32)] ~= int32(0)
|
||||||
|
dst = dst[4:]
|
||||||
|
hostarch.ByteOrder.PutUint64(dst[:8], uint64(s.Rdev))
|
||||||
|
dst = dst[8:]
|
||||||
|
hostarch.ByteOrder.PutUint64(dst[:8], uint64(s.Size))
|
||||||
|
dst = dst[8:]
|
||||||
|
hostarch.ByteOrder.PutUint64(dst[:8], uint64(s.Blksize))
|
||||||
|
dst = dst[8:]
|
||||||
|
hostarch.ByteOrder.PutUint64(dst[:8], uint64(s.Blocks))
|
||||||
|
dst = dst[8:]
|
||||||
|
dst = s.ATime.MarshalUnsafe(dst)
|
||||||
|
dst = s.MTime.MarshalUnsafe(dst)
|
||||||
|
dst = s.CTime.MarshalUnsafe(dst)
|
||||||
|
// Padding: dst[:sizeof(int64)*3] ~= [3]int64{0}
|
||||||
|
dst = dst[8*(3):]
|
||||||
|
return dst
|
||||||
|
}
|
||||||
|
|
||||||
|
// UnmarshalBytes implements marshal.Marshallable.UnmarshalBytes.
|
||||||
|
func (s *Stat) UnmarshalBytes(src []byte) []byte {
|
||||||
|
s.Dev = uint64(hostarch.ByteOrder.Uint64(src[:8]))
|
||||||
|
src = src[8:]
|
||||||
|
s.Ino = uint64(hostarch.ByteOrder.Uint64(src[:8]))
|
||||||
|
src = src[8:]
|
||||||
|
s.Nlink = uint64(hostarch.ByteOrder.Uint64(src[:8]))
|
||||||
|
src = src[8:]
|
||||||
|
s.Mode = uint32(hostarch.ByteOrder.Uint32(src[:4]))
|
||||||
|
src = src[4:]
|
||||||
|
s.UID = uint32(hostarch.ByteOrder.Uint32(src[:4]))
|
||||||
|
src = src[4:]
|
||||||
|
s.GID = uint32(hostarch.ByteOrder.Uint32(src[:4]))
|
||||||
|
src = src[4:]
|
||||||
|
// Padding: var _ int32 ~= src[:sizeof(int32)]
|
||||||
|
src = src[4:]
|
||||||
|
s.Rdev = uint64(hostarch.ByteOrder.Uint64(src[:8]))
|
||||||
|
src = src[8:]
|
||||||
|
s.Size = int64(hostarch.ByteOrder.Uint64(src[:8]))
|
||||||
|
src = src[8:]
|
||||||
|
s.Blksize = int64(hostarch.ByteOrder.Uint64(src[:8]))
|
||||||
|
src = src[8:]
|
||||||
|
s.Blocks = int64(hostarch.ByteOrder.Uint64(src[:8]))
|
||||||
|
src = src[8:]
|
||||||
|
src = s.ATime.UnmarshalUnsafe(src)
|
||||||
|
src = s.MTime.UnmarshalUnsafe(src)
|
||||||
|
src = s.CTime.UnmarshalUnsafe(src)
|
||||||
|
// Padding: ~ copy([3]int64(s._), src[:sizeof(int64)*3])
|
||||||
|
src = src[8*(3):]
|
||||||
|
return src
|
||||||
|
}
|
||||||
|
|
||||||
|
// Packed implements marshal.Marshallable.Packed.
|
||||||
|
//
|
||||||
|
//go:nosplit
|
||||||
|
func (s *Stat) Packed() bool {
|
||||||
|
return s.ATime.Packed() && s.CTime.Packed() && s.MTime.Packed()
|
||||||
|
}
|
||||||
|
|
||||||
|
// MarshalUnsafe implements marshal.Marshallable.MarshalUnsafe.
|
||||||
|
func (s *Stat) MarshalUnsafe(dst []byte) []byte {
|
||||||
|
if s.ATime.Packed() && s.CTime.Packed() && s.MTime.Packed() {
|
||||||
|
size := s.SizeBytes()
|
||||||
|
gohacks.Memmove(unsafe.Pointer(&dst[0]), unsafe.Pointer(s), uintptr(size))
|
||||||
|
return dst[size:]
|
||||||
|
}
|
||||||
|
// Type Stat doesn't have a packed layout in memory, fallback to MarshalBytes.
|
||||||
|
return s.MarshalBytes(dst)
|
||||||
|
}
|
||||||
|
|
||||||
|
// UnmarshalUnsafe implements marshal.Marshallable.UnmarshalUnsafe.
|
||||||
|
func (s *Stat) UnmarshalUnsafe(src []byte) []byte {
|
||||||
|
if s.ATime.Packed() && s.CTime.Packed() && s.MTime.Packed() {
|
||||||
|
size := s.SizeBytes()
|
||||||
|
gohacks.Memmove(unsafe.Pointer(s), unsafe.Pointer(&src[0]), uintptr(size))
|
||||||
|
return src[size:]
|
||||||
|
}
|
||||||
|
// Type Stat doesn't have a packed layout in memory, fallback to UnmarshalBytes.
|
||||||
|
return s.UnmarshalBytes(src)
|
||||||
|
}
|
||||||
|
|
||||||
|
// CopyOutN implements marshal.Marshallable.CopyOutN.
|
||||||
|
func (s *Stat) CopyOutN(cc marshal.CopyContext, addr hostarch.Addr, limit int) (int, error) {
|
||||||
|
if !s.ATime.Packed() && s.CTime.Packed() && s.MTime.Packed() {
|
||||||
|
// Type Stat doesn't have a packed layout in memory, fall back to MarshalBytes.
|
||||||
|
buf := cc.CopyScratchBuffer(s.SizeBytes()) // escapes: okay.
|
||||||
|
s.MarshalBytes(buf) // escapes: fallback.
|
||||||
|
return cc.CopyOutBytes(addr, buf[:limit]) // escapes: okay.
|
||||||
|
}
|
||||||
|
|
||||||
|
// Construct a slice backed by dst's underlying memory.
|
||||||
|
var buf []byte
|
||||||
|
hdr := (*reflect.SliceHeader)(unsafe.Pointer(&buf))
|
||||||
|
hdr.Data = uintptr(gohacks.Noescape(unsafe.Pointer(s)))
|
||||||
|
hdr.Len = s.SizeBytes()
|
||||||
|
hdr.Cap = s.SizeBytes()
|
||||||
|
|
||||||
|
length, err := cc.CopyOutBytes(addr, buf[:limit]) // escapes: okay.
|
||||||
|
// Since we bypassed the compiler's escape analysis, indicate that s
|
||||||
|
// must live until the use above.
|
||||||
|
runtime.KeepAlive(s) // escapes: replaced by intrinsic.
|
||||||
|
return length, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// CopyOut implements marshal.Marshallable.CopyOut.
|
||||||
|
func (s *Stat) CopyOut(cc marshal.CopyContext, addr hostarch.Addr) (int, error) {
|
||||||
|
return s.CopyOutN(cc, addr, s.SizeBytes())
|
||||||
|
}
|
||||||
|
|
||||||
|
// CopyInN implements marshal.Marshallable.CopyInN.
|
||||||
|
func (s *Stat) CopyInN(cc marshal.CopyContext, addr hostarch.Addr, limit int) (int, error) {
|
||||||
|
if !s.ATime.Packed() && s.CTime.Packed() && s.MTime.Packed() {
|
||||||
|
// Type Stat doesn't have a packed layout in memory, fall back to UnmarshalBytes.
|
||||||
|
buf := cc.CopyScratchBuffer(s.SizeBytes()) // escapes: okay.
|
||||||
|
length, err := cc.CopyInBytes(addr, buf[:limit]) // escapes: okay.
|
||||||
|
// Unmarshal unconditionally. If we had a short copy-in, this results in a
|
||||||
|
// partially unmarshalled struct.
|
||||||
|
s.UnmarshalBytes(buf) // escapes: fallback.
|
||||||
|
return length, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Construct a slice backed by dst's underlying memory.
|
||||||
|
var buf []byte
|
||||||
|
hdr := (*reflect.SliceHeader)(unsafe.Pointer(&buf))
|
||||||
|
hdr.Data = uintptr(gohacks.Noescape(unsafe.Pointer(s)))
|
||||||
|
hdr.Len = s.SizeBytes()
|
||||||
|
hdr.Cap = s.SizeBytes()
|
||||||
|
|
||||||
|
length, err := cc.CopyInBytes(addr, buf[:limit]) // escapes: okay.
|
||||||
|
// Since we bypassed the compiler's escape analysis, indicate that s
|
||||||
|
// must live until the use above.
|
||||||
|
runtime.KeepAlive(s) // escapes: replaced by intrinsic.
|
||||||
|
return length, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// CopyIn implements marshal.Marshallable.CopyIn.
|
||||||
|
func (s *Stat) CopyIn(cc marshal.CopyContext, addr hostarch.Addr) (int, error) {
|
||||||
|
return s.CopyInN(cc, addr, s.SizeBytes())
|
||||||
|
}
|
||||||
|
|
||||||
|
// WriteTo implements io.WriterTo.WriteTo.
|
||||||
|
func (s *Stat) WriteTo(writer io.Writer) (int64, error) {
|
||||||
|
if !s.ATime.Packed() && s.CTime.Packed() && s.MTime.Packed() {
|
||||||
|
// Type Stat doesn't have a packed layout in memory, fall back to MarshalBytes.
|
||||||
|
buf := make([]byte, s.SizeBytes())
|
||||||
|
s.MarshalBytes(buf)
|
||||||
|
length, err := writer.Write(buf)
|
||||||
|
return int64(length), err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Construct a slice backed by dst's underlying memory.
|
||||||
|
var buf []byte
|
||||||
|
hdr := (*reflect.SliceHeader)(unsafe.Pointer(&buf))
|
||||||
|
hdr.Data = uintptr(gohacks.Noescape(unsafe.Pointer(s)))
|
||||||
|
hdr.Len = s.SizeBytes()
|
||||||
|
hdr.Cap = s.SizeBytes()
|
||||||
|
|
||||||
|
length, err := writer.Write(buf)
|
||||||
|
// Since we bypassed the compiler's escape analysis, indicate that s
|
||||||
|
// must live until the use above.
|
||||||
|
runtime.KeepAlive(s) // escapes: replaced by intrinsic.
|
||||||
|
return int64(length), err
|
||||||
|
}
|
||||||
|
|
||||||
|
// SizeBytes implements marshal.Marshallable.SizeBytes.
|
||||||
|
func (p *PtraceRegs) SizeBytes() int {
|
||||||
|
return 216
|
||||||
|
}
|
||||||
|
|
||||||
|
// MarshalBytes implements marshal.Marshallable.MarshalBytes.
|
||||||
|
func (p *PtraceRegs) MarshalBytes(dst []byte) []byte {
|
||||||
|
hostarch.ByteOrder.PutUint64(dst[:8], uint64(p.R15))
|
||||||
|
dst = dst[8:]
|
||||||
|
hostarch.ByteOrder.PutUint64(dst[:8], uint64(p.R14))
|
||||||
|
dst = dst[8:]
|
||||||
|
hostarch.ByteOrder.PutUint64(dst[:8], uint64(p.R13))
|
||||||
|
dst = dst[8:]
|
||||||
|
hostarch.ByteOrder.PutUint64(dst[:8], uint64(p.R12))
|
||||||
|
dst = dst[8:]
|
||||||
|
hostarch.ByteOrder.PutUint64(dst[:8], uint64(p.Rbp))
|
||||||
|
dst = dst[8:]
|
||||||
|
hostarch.ByteOrder.PutUint64(dst[:8], uint64(p.Rbx))
|
||||||
|
dst = dst[8:]
|
||||||
|
hostarch.ByteOrder.PutUint64(dst[:8], uint64(p.R11))
|
||||||
|
dst = dst[8:]
|
||||||
|
hostarch.ByteOrder.PutUint64(dst[:8], uint64(p.R10))
|
||||||
|
dst = dst[8:]
|
||||||
|
hostarch.ByteOrder.PutUint64(dst[:8], uint64(p.R9))
|
||||||
|
dst = dst[8:]
|
||||||
|
hostarch.ByteOrder.PutUint64(dst[:8], uint64(p.R8))
|
||||||
|
dst = dst[8:]
|
||||||
|
hostarch.ByteOrder.PutUint64(dst[:8], uint64(p.Rax))
|
||||||
|
dst = dst[8:]
|
||||||
|
hostarch.ByteOrder.PutUint64(dst[:8], uint64(p.Rcx))
|
||||||
|
dst = dst[8:]
|
||||||
|
hostarch.ByteOrder.PutUint64(dst[:8], uint64(p.Rdx))
|
||||||
|
dst = dst[8:]
|
||||||
|
hostarch.ByteOrder.PutUint64(dst[:8], uint64(p.Rsi))
|
||||||
|
dst = dst[8:]
|
||||||
|
hostarch.ByteOrder.PutUint64(dst[:8], uint64(p.Rdi))
|
||||||
|
dst = dst[8:]
|
||||||
|
hostarch.ByteOrder.PutUint64(dst[:8], uint64(p.Orig_rax))
|
||||||
|
dst = dst[8:]
|
||||||
|
hostarch.ByteOrder.PutUint64(dst[:8], uint64(p.Rip))
|
||||||
|
dst = dst[8:]
|
||||||
|
hostarch.ByteOrder.PutUint64(dst[:8], uint64(p.Cs))
|
||||||
|
dst = dst[8:]
|
||||||
|
hostarch.ByteOrder.PutUint64(dst[:8], uint64(p.Eflags))
|
||||||
|
dst = dst[8:]
|
||||||
|
hostarch.ByteOrder.PutUint64(dst[:8], uint64(p.Rsp))
|
||||||
|
dst = dst[8:]
|
||||||
|
hostarch.ByteOrder.PutUint64(dst[:8], uint64(p.Ss))
|
||||||
|
dst = dst[8:]
|
||||||
|
hostarch.ByteOrder.PutUint64(dst[:8], uint64(p.Fs_base))
|
||||||
|
dst = dst[8:]
|
||||||
|
hostarch.ByteOrder.PutUint64(dst[:8], uint64(p.Gs_base))
|
||||||
|
dst = dst[8:]
|
||||||
|
hostarch.ByteOrder.PutUint64(dst[:8], uint64(p.Ds))
|
||||||
|
dst = dst[8:]
|
||||||
|
hostarch.ByteOrder.PutUint64(dst[:8], uint64(p.Es))
|
||||||
|
dst = dst[8:]
|
||||||
|
hostarch.ByteOrder.PutUint64(dst[:8], uint64(p.Fs))
|
||||||
|
dst = dst[8:]
|
||||||
|
hostarch.ByteOrder.PutUint64(dst[:8], uint64(p.Gs))
|
||||||
|
dst = dst[8:]
|
||||||
|
return dst
|
||||||
|
}
|
||||||
|
|
||||||
|
// UnmarshalBytes implements marshal.Marshallable.UnmarshalBytes.
|
||||||
|
func (p *PtraceRegs) UnmarshalBytes(src []byte) []byte {
|
||||||
|
p.R15 = uint64(hostarch.ByteOrder.Uint64(src[:8]))
|
||||||
|
src = src[8:]
|
||||||
|
p.R14 = uint64(hostarch.ByteOrder.Uint64(src[:8]))
|
||||||
|
src = src[8:]
|
||||||
|
p.R13 = uint64(hostarch.ByteOrder.Uint64(src[:8]))
|
||||||
|
src = src[8:]
|
||||||
|
p.R12 = uint64(hostarch.ByteOrder.Uint64(src[:8]))
|
||||||
|
src = src[8:]
|
||||||
|
p.Rbp = uint64(hostarch.ByteOrder.Uint64(src[:8]))
|
||||||
|
src = src[8:]
|
||||||
|
p.Rbx = uint64(hostarch.ByteOrder.Uint64(src[:8]))
|
||||||
|
src = src[8:]
|
||||||
|
p.R11 = uint64(hostarch.ByteOrder.Uint64(src[:8]))
|
||||||
|
src = src[8:]
|
||||||
|
p.R10 = uint64(hostarch.ByteOrder.Uint64(src[:8]))
|
||||||
|
src = src[8:]
|
||||||
|
p.R9 = uint64(hostarch.ByteOrder.Uint64(src[:8]))
|
||||||
|
src = src[8:]
|
||||||
|
p.R8 = uint64(hostarch.ByteOrder.Uint64(src[:8]))
|
||||||
|
src = src[8:]
|
||||||
|
p.Rax = uint64(hostarch.ByteOrder.Uint64(src[:8]))
|
||||||
|
src = src[8:]
|
||||||
|
p.Rcx = uint64(hostarch.ByteOrder.Uint64(src[:8]))
|
||||||
|
src = src[8:]
|
||||||
|
p.Rdx = uint64(hostarch.ByteOrder.Uint64(src[:8]))
|
||||||
|
src = src[8:]
|
||||||
|
p.Rsi = uint64(hostarch.ByteOrder.Uint64(src[:8]))
|
||||||
|
src = src[8:]
|
||||||
|
p.Rdi = uint64(hostarch.ByteOrder.Uint64(src[:8]))
|
||||||
|
src = src[8:]
|
||||||
|
p.Orig_rax = uint64(hostarch.ByteOrder.Uint64(src[:8]))
|
||||||
|
src = src[8:]
|
||||||
|
p.Rip = uint64(hostarch.ByteOrder.Uint64(src[:8]))
|
||||||
|
src = src[8:]
|
||||||
|
p.Cs = uint64(hostarch.ByteOrder.Uint64(src[:8]))
|
||||||
|
src = src[8:]
|
||||||
|
p.Eflags = uint64(hostarch.ByteOrder.Uint64(src[:8]))
|
||||||
|
src = src[8:]
|
||||||
|
p.Rsp = uint64(hostarch.ByteOrder.Uint64(src[:8]))
|
||||||
|
src = src[8:]
|
||||||
|
p.Ss = uint64(hostarch.ByteOrder.Uint64(src[:8]))
|
||||||
|
src = src[8:]
|
||||||
|
p.Fs_base = uint64(hostarch.ByteOrder.Uint64(src[:8]))
|
||||||
|
src = src[8:]
|
||||||
|
p.Gs_base = uint64(hostarch.ByteOrder.Uint64(src[:8]))
|
||||||
|
src = src[8:]
|
||||||
|
p.Ds = uint64(hostarch.ByteOrder.Uint64(src[:8]))
|
||||||
|
src = src[8:]
|
||||||
|
p.Es = uint64(hostarch.ByteOrder.Uint64(src[:8]))
|
||||||
|
src = src[8:]
|
||||||
|
p.Fs = uint64(hostarch.ByteOrder.Uint64(src[:8]))
|
||||||
|
src = src[8:]
|
||||||
|
p.Gs = uint64(hostarch.ByteOrder.Uint64(src[:8]))
|
||||||
|
src = src[8:]
|
||||||
|
return src
|
||||||
|
}
|
||||||
|
|
||||||
|
// Packed implements marshal.Marshallable.Packed.
|
||||||
|
//
|
||||||
|
//go:nosplit
|
||||||
|
func (p *PtraceRegs) Packed() bool {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
// MarshalUnsafe implements marshal.Marshallable.MarshalUnsafe.
|
||||||
|
func (p *PtraceRegs) MarshalUnsafe(dst []byte) []byte {
|
||||||
|
size := p.SizeBytes()
|
||||||
|
gohacks.Memmove(unsafe.Pointer(&dst[0]), unsafe.Pointer(p), uintptr(size))
|
||||||
|
return dst[size:]
|
||||||
|
}
|
||||||
|
|
||||||
|
// UnmarshalUnsafe implements marshal.Marshallable.UnmarshalUnsafe.
|
||||||
|
func (p *PtraceRegs) UnmarshalUnsafe(src []byte) []byte {
|
||||||
|
size := p.SizeBytes()
|
||||||
|
gohacks.Memmove(unsafe.Pointer(p), unsafe.Pointer(&src[0]), uintptr(size))
|
||||||
|
return src[size:]
|
||||||
|
}
|
||||||
|
|
||||||
|
// CopyOutN implements marshal.Marshallable.CopyOutN.
|
||||||
|
func (p *PtraceRegs) CopyOutN(cc marshal.CopyContext, addr hostarch.Addr, limit int) (int, error) {
|
||||||
|
// Construct a slice backed by dst's underlying memory.
|
||||||
|
var buf []byte
|
||||||
|
hdr := (*reflect.SliceHeader)(unsafe.Pointer(&buf))
|
||||||
|
hdr.Data = uintptr(gohacks.Noescape(unsafe.Pointer(p)))
|
||||||
|
hdr.Len = p.SizeBytes()
|
||||||
|
hdr.Cap = p.SizeBytes()
|
||||||
|
|
||||||
|
length, err := cc.CopyOutBytes(addr, buf[:limit]) // escapes: okay.
|
||||||
|
// Since we bypassed the compiler's escape analysis, indicate that p
|
||||||
|
// must live until the use above.
|
||||||
|
runtime.KeepAlive(p) // escapes: replaced by intrinsic.
|
||||||
|
return length, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// CopyOut implements marshal.Marshallable.CopyOut.
|
||||||
|
func (p *PtraceRegs) CopyOut(cc marshal.CopyContext, addr hostarch.Addr) (int, error) {
|
||||||
|
return p.CopyOutN(cc, addr, p.SizeBytes())
|
||||||
|
}
|
||||||
|
|
||||||
|
// CopyInN implements marshal.Marshallable.CopyInN.
|
||||||
|
func (p *PtraceRegs) CopyInN(cc marshal.CopyContext, addr hostarch.Addr, limit int) (int, error) {
|
||||||
|
// Construct a slice backed by dst's underlying memory.
|
||||||
|
var buf []byte
|
||||||
|
hdr := (*reflect.SliceHeader)(unsafe.Pointer(&buf))
|
||||||
|
hdr.Data = uintptr(gohacks.Noescape(unsafe.Pointer(p)))
|
||||||
|
hdr.Len = p.SizeBytes()
|
||||||
|
hdr.Cap = p.SizeBytes()
|
||||||
|
|
||||||
|
length, err := cc.CopyInBytes(addr, buf[:limit]) // escapes: okay.
|
||||||
|
// Since we bypassed the compiler's escape analysis, indicate that p
|
||||||
|
// must live until the use above.
|
||||||
|
runtime.KeepAlive(p) // escapes: replaced by intrinsic.
|
||||||
|
return length, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// CopyIn implements marshal.Marshallable.CopyIn.
|
||||||
|
func (p *PtraceRegs) CopyIn(cc marshal.CopyContext, addr hostarch.Addr) (int, error) {
|
||||||
|
return p.CopyInN(cc, addr, p.SizeBytes())
|
||||||
|
}
|
||||||
|
|
||||||
|
// WriteTo implements io.WriterTo.WriteTo.
|
||||||
|
func (p *PtraceRegs) WriteTo(writer io.Writer) (int64, error) {
|
||||||
|
// Construct a slice backed by dst's underlying memory.
|
||||||
|
var buf []byte
|
||||||
|
hdr := (*reflect.SliceHeader)(unsafe.Pointer(&buf))
|
||||||
|
hdr.Data = uintptr(gohacks.Noescape(unsafe.Pointer(p)))
|
||||||
|
hdr.Len = p.SizeBytes()
|
||||||
|
hdr.Cap = p.SizeBytes()
|
||||||
|
|
||||||
|
length, err := writer.Write(buf)
|
||||||
|
// Since we bypassed the compiler's escape analysis, indicate that p
|
||||||
|
// must live until the use above.
|
||||||
|
runtime.KeepAlive(p) // escapes: replaced by intrinsic.
|
||||||
|
return int64(length), err
|
||||||
|
}
|
||||||
|
|
||||||
|
// SizeBytes implements marshal.Marshallable.SizeBytes.
|
||||||
|
func (s *SemidDS) SizeBytes() int {
|
||||||
|
return 40 +
|
||||||
|
(*IPCPerm)(nil).SizeBytes() +
|
||||||
|
(*TimeT)(nil).SizeBytes() +
|
||||||
|
(*TimeT)(nil).SizeBytes()
|
||||||
|
}
|
||||||
|
|
||||||
|
// MarshalBytes implements marshal.Marshallable.MarshalBytes.
|
||||||
|
func (s *SemidDS) MarshalBytes(dst []byte) []byte {
|
||||||
|
dst = s.SemPerm.MarshalUnsafe(dst)
|
||||||
|
dst = s.SemOTime.MarshalUnsafe(dst)
|
||||||
|
hostarch.ByteOrder.PutUint64(dst[:8], uint64(s.unused1))
|
||||||
|
dst = dst[8:]
|
||||||
|
dst = s.SemCTime.MarshalUnsafe(dst)
|
||||||
|
hostarch.ByteOrder.PutUint64(dst[:8], uint64(s.unused2))
|
||||||
|
dst = dst[8:]
|
||||||
|
hostarch.ByteOrder.PutUint64(dst[:8], uint64(s.SemNSems))
|
||||||
|
dst = dst[8:]
|
||||||
|
hostarch.ByteOrder.PutUint64(dst[:8], uint64(s.unused3))
|
||||||
|
dst = dst[8:]
|
||||||
|
hostarch.ByteOrder.PutUint64(dst[:8], uint64(s.unused4))
|
||||||
|
dst = dst[8:]
|
||||||
|
return dst
|
||||||
|
}
|
||||||
|
|
||||||
|
// UnmarshalBytes implements marshal.Marshallable.UnmarshalBytes.
|
||||||
|
func (s *SemidDS) UnmarshalBytes(src []byte) []byte {
|
||||||
|
src = s.SemPerm.UnmarshalUnsafe(src)
|
||||||
|
src = s.SemOTime.UnmarshalUnsafe(src)
|
||||||
|
s.unused1 = uint64(hostarch.ByteOrder.Uint64(src[:8]))
|
||||||
|
src = src[8:]
|
||||||
|
src = s.SemCTime.UnmarshalUnsafe(src)
|
||||||
|
s.unused2 = uint64(hostarch.ByteOrder.Uint64(src[:8]))
|
||||||
|
src = src[8:]
|
||||||
|
s.SemNSems = uint64(hostarch.ByteOrder.Uint64(src[:8]))
|
||||||
|
src = src[8:]
|
||||||
|
s.unused3 = uint64(hostarch.ByteOrder.Uint64(src[:8]))
|
||||||
|
src = src[8:]
|
||||||
|
s.unused4 = uint64(hostarch.ByteOrder.Uint64(src[:8]))
|
||||||
|
src = src[8:]
|
||||||
|
return src
|
||||||
|
}
|
||||||
|
|
||||||
|
// Packed implements marshal.Marshallable.Packed.
|
||||||
|
//
|
||||||
|
//go:nosplit
|
||||||
|
func (s *SemidDS) Packed() bool {
|
||||||
|
return s.SemCTime.Packed() && s.SemOTime.Packed() && s.SemPerm.Packed()
|
||||||
|
}
|
||||||
|
|
||||||
|
// MarshalUnsafe implements marshal.Marshallable.MarshalUnsafe.
|
||||||
|
func (s *SemidDS) MarshalUnsafe(dst []byte) []byte {
|
||||||
|
if s.SemCTime.Packed() && s.SemOTime.Packed() && s.SemPerm.Packed() {
|
||||||
|
size := s.SizeBytes()
|
||||||
|
gohacks.Memmove(unsafe.Pointer(&dst[0]), unsafe.Pointer(s), uintptr(size))
|
||||||
|
return dst[size:]
|
||||||
|
}
|
||||||
|
// Type SemidDS doesn't have a packed layout in memory, fallback to MarshalBytes.
|
||||||
|
return s.MarshalBytes(dst)
|
||||||
|
}
|
||||||
|
|
||||||
|
// UnmarshalUnsafe implements marshal.Marshallable.UnmarshalUnsafe.
|
||||||
|
func (s *SemidDS) UnmarshalUnsafe(src []byte) []byte {
|
||||||
|
if s.SemCTime.Packed() && s.SemOTime.Packed() && s.SemPerm.Packed() {
|
||||||
|
size := s.SizeBytes()
|
||||||
|
gohacks.Memmove(unsafe.Pointer(s), unsafe.Pointer(&src[0]), uintptr(size))
|
||||||
|
return src[size:]
|
||||||
|
}
|
||||||
|
// Type SemidDS doesn't have a packed layout in memory, fallback to UnmarshalBytes.
|
||||||
|
return s.UnmarshalBytes(src)
|
||||||
|
}
|
||||||
|
|
||||||
|
// CopyOutN implements marshal.Marshallable.CopyOutN.
|
||||||
|
func (s *SemidDS) CopyOutN(cc marshal.CopyContext, addr hostarch.Addr, limit int) (int, error) {
|
||||||
|
if !s.SemCTime.Packed() && s.SemOTime.Packed() && s.SemPerm.Packed() {
|
||||||
|
// Type SemidDS doesn't have a packed layout in memory, fall back to MarshalBytes.
|
||||||
|
buf := cc.CopyScratchBuffer(s.SizeBytes()) // escapes: okay.
|
||||||
|
s.MarshalBytes(buf) // escapes: fallback.
|
||||||
|
return cc.CopyOutBytes(addr, buf[:limit]) // escapes: okay.
|
||||||
|
}
|
||||||
|
|
||||||
|
// Construct a slice backed by dst's underlying memory.
|
||||||
|
var buf []byte
|
||||||
|
hdr := (*reflect.SliceHeader)(unsafe.Pointer(&buf))
|
||||||
|
hdr.Data = uintptr(gohacks.Noescape(unsafe.Pointer(s)))
|
||||||
|
hdr.Len = s.SizeBytes()
|
||||||
|
hdr.Cap = s.SizeBytes()
|
||||||
|
|
||||||
|
length, err := cc.CopyOutBytes(addr, buf[:limit]) // escapes: okay.
|
||||||
|
// Since we bypassed the compiler's escape analysis, indicate that s
|
||||||
|
// must live until the use above.
|
||||||
|
runtime.KeepAlive(s) // escapes: replaced by intrinsic.
|
||||||
|
return length, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// CopyOut implements marshal.Marshallable.CopyOut.
|
||||||
|
func (s *SemidDS) CopyOut(cc marshal.CopyContext, addr hostarch.Addr) (int, error) {
|
||||||
|
return s.CopyOutN(cc, addr, s.SizeBytes())
|
||||||
|
}
|
||||||
|
|
||||||
|
// CopyInN implements marshal.Marshallable.CopyInN.
|
||||||
|
func (s *SemidDS) CopyInN(cc marshal.CopyContext, addr hostarch.Addr, limit int) (int, error) {
|
||||||
|
if !s.SemCTime.Packed() && s.SemOTime.Packed() && s.SemPerm.Packed() {
|
||||||
|
// Type SemidDS doesn't have a packed layout in memory, fall back to UnmarshalBytes.
|
||||||
|
buf := cc.CopyScratchBuffer(s.SizeBytes()) // escapes: okay.
|
||||||
|
length, err := cc.CopyInBytes(addr, buf[:limit]) // escapes: okay.
|
||||||
|
// Unmarshal unconditionally. If we had a short copy-in, this results in a
|
||||||
|
// partially unmarshalled struct.
|
||||||
|
s.UnmarshalBytes(buf) // escapes: fallback.
|
||||||
|
return length, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Construct a slice backed by dst's underlying memory.
|
||||||
|
var buf []byte
|
||||||
|
hdr := (*reflect.SliceHeader)(unsafe.Pointer(&buf))
|
||||||
|
hdr.Data = uintptr(gohacks.Noescape(unsafe.Pointer(s)))
|
||||||
|
hdr.Len = s.SizeBytes()
|
||||||
|
hdr.Cap = s.SizeBytes()
|
||||||
|
|
||||||
|
length, err := cc.CopyInBytes(addr, buf[:limit]) // escapes: okay.
|
||||||
|
// Since we bypassed the compiler's escape analysis, indicate that s
|
||||||
|
// must live until the use above.
|
||||||
|
runtime.KeepAlive(s) // escapes: replaced by intrinsic.
|
||||||
|
return length, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// CopyIn implements marshal.Marshallable.CopyIn.
|
||||||
|
func (s *SemidDS) CopyIn(cc marshal.CopyContext, addr hostarch.Addr) (int, error) {
|
||||||
|
return s.CopyInN(cc, addr, s.SizeBytes())
|
||||||
|
}
|
||||||
|
|
||||||
|
// WriteTo implements io.WriterTo.WriteTo.
|
||||||
|
func (s *SemidDS) WriteTo(writer io.Writer) (int64, error) {
|
||||||
|
if !s.SemCTime.Packed() && s.SemOTime.Packed() && s.SemPerm.Packed() {
|
||||||
|
// Type SemidDS doesn't have a packed layout in memory, fall back to MarshalBytes.
|
||||||
|
buf := make([]byte, s.SizeBytes())
|
||||||
|
s.MarshalBytes(buf)
|
||||||
|
length, err := writer.Write(buf)
|
||||||
|
return int64(length), err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Construct a slice backed by dst's underlying memory.
|
||||||
|
var buf []byte
|
||||||
|
hdr := (*reflect.SliceHeader)(unsafe.Pointer(&buf))
|
||||||
|
hdr.Data = uintptr(gohacks.Noescape(unsafe.Pointer(s)))
|
||||||
|
hdr.Len = s.SizeBytes()
|
||||||
|
hdr.Cap = s.SizeBytes()
|
||||||
|
|
||||||
|
length, err := writer.Write(buf)
|
||||||
|
// Since we bypassed the compiler's escape analysis, indicate that s
|
||||||
|
// must live until the use above.
|
||||||
|
runtime.KeepAlive(s) // escapes: replaced by intrinsic.
|
||||||
|
return int64(length), err
|
||||||
|
}
|
||||||
119
pkg/abi/linux/linux_amd64_state_autogen.go
Normal file
119
pkg/abi/linux/linux_amd64_state_autogen.go
Normal file
|
|
@ -0,0 +1,119 @@
|
||||||
|
// automatically generated by stateify.
|
||||||
|
|
||||||
|
//go:build amd64 && amd64 && amd64 && amd64 && amd64 && amd64
|
||||||
|
// +build amd64,amd64,amd64,amd64,amd64,amd64
|
||||||
|
|
||||||
|
package linux
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
|
||||||
|
"github.com/sagernet/gvisor/pkg/state"
|
||||||
|
)
|
||||||
|
|
||||||
|
func (p *PtraceRegs) StateTypeName() string {
|
||||||
|
return "pkg/abi/linux.PtraceRegs"
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *PtraceRegs) StateFields() []string {
|
||||||
|
return []string{
|
||||||
|
"R15",
|
||||||
|
"R14",
|
||||||
|
"R13",
|
||||||
|
"R12",
|
||||||
|
"Rbp",
|
||||||
|
"Rbx",
|
||||||
|
"R11",
|
||||||
|
"R10",
|
||||||
|
"R9",
|
||||||
|
"R8",
|
||||||
|
"Rax",
|
||||||
|
"Rcx",
|
||||||
|
"Rdx",
|
||||||
|
"Rsi",
|
||||||
|
"Rdi",
|
||||||
|
"Orig_rax",
|
||||||
|
"Rip",
|
||||||
|
"Cs",
|
||||||
|
"Eflags",
|
||||||
|
"Rsp",
|
||||||
|
"Ss",
|
||||||
|
"Fs_base",
|
||||||
|
"Gs_base",
|
||||||
|
"Ds",
|
||||||
|
"Es",
|
||||||
|
"Fs",
|
||||||
|
"Gs",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *PtraceRegs) beforeSave() {}
|
||||||
|
|
||||||
|
// +checklocksignore
|
||||||
|
func (p *PtraceRegs) StateSave(stateSinkObject state.Sink) {
|
||||||
|
p.beforeSave()
|
||||||
|
stateSinkObject.Save(0, &p.R15)
|
||||||
|
stateSinkObject.Save(1, &p.R14)
|
||||||
|
stateSinkObject.Save(2, &p.R13)
|
||||||
|
stateSinkObject.Save(3, &p.R12)
|
||||||
|
stateSinkObject.Save(4, &p.Rbp)
|
||||||
|
stateSinkObject.Save(5, &p.Rbx)
|
||||||
|
stateSinkObject.Save(6, &p.R11)
|
||||||
|
stateSinkObject.Save(7, &p.R10)
|
||||||
|
stateSinkObject.Save(8, &p.R9)
|
||||||
|
stateSinkObject.Save(9, &p.R8)
|
||||||
|
stateSinkObject.Save(10, &p.Rax)
|
||||||
|
stateSinkObject.Save(11, &p.Rcx)
|
||||||
|
stateSinkObject.Save(12, &p.Rdx)
|
||||||
|
stateSinkObject.Save(13, &p.Rsi)
|
||||||
|
stateSinkObject.Save(14, &p.Rdi)
|
||||||
|
stateSinkObject.Save(15, &p.Orig_rax)
|
||||||
|
stateSinkObject.Save(16, &p.Rip)
|
||||||
|
stateSinkObject.Save(17, &p.Cs)
|
||||||
|
stateSinkObject.Save(18, &p.Eflags)
|
||||||
|
stateSinkObject.Save(19, &p.Rsp)
|
||||||
|
stateSinkObject.Save(20, &p.Ss)
|
||||||
|
stateSinkObject.Save(21, &p.Fs_base)
|
||||||
|
stateSinkObject.Save(22, &p.Gs_base)
|
||||||
|
stateSinkObject.Save(23, &p.Ds)
|
||||||
|
stateSinkObject.Save(24, &p.Es)
|
||||||
|
stateSinkObject.Save(25, &p.Fs)
|
||||||
|
stateSinkObject.Save(26, &p.Gs)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *PtraceRegs) afterLoad(context.Context) {}
|
||||||
|
|
||||||
|
// +checklocksignore
|
||||||
|
func (p *PtraceRegs) StateLoad(ctx context.Context, stateSourceObject state.Source) {
|
||||||
|
stateSourceObject.Load(0, &p.R15)
|
||||||
|
stateSourceObject.Load(1, &p.R14)
|
||||||
|
stateSourceObject.Load(2, &p.R13)
|
||||||
|
stateSourceObject.Load(3, &p.R12)
|
||||||
|
stateSourceObject.Load(4, &p.Rbp)
|
||||||
|
stateSourceObject.Load(5, &p.Rbx)
|
||||||
|
stateSourceObject.Load(6, &p.R11)
|
||||||
|
stateSourceObject.Load(7, &p.R10)
|
||||||
|
stateSourceObject.Load(8, &p.R9)
|
||||||
|
stateSourceObject.Load(9, &p.R8)
|
||||||
|
stateSourceObject.Load(10, &p.Rax)
|
||||||
|
stateSourceObject.Load(11, &p.Rcx)
|
||||||
|
stateSourceObject.Load(12, &p.Rdx)
|
||||||
|
stateSourceObject.Load(13, &p.Rsi)
|
||||||
|
stateSourceObject.Load(14, &p.Rdi)
|
||||||
|
stateSourceObject.Load(15, &p.Orig_rax)
|
||||||
|
stateSourceObject.Load(16, &p.Rip)
|
||||||
|
stateSourceObject.Load(17, &p.Cs)
|
||||||
|
stateSourceObject.Load(18, &p.Eflags)
|
||||||
|
stateSourceObject.Load(19, &p.Rsp)
|
||||||
|
stateSourceObject.Load(20, &p.Ss)
|
||||||
|
stateSourceObject.Load(21, &p.Fs_base)
|
||||||
|
stateSourceObject.Load(22, &p.Gs_base)
|
||||||
|
stateSourceObject.Load(23, &p.Ds)
|
||||||
|
stateSourceObject.Load(24, &p.Es)
|
||||||
|
stateSourceObject.Load(25, &p.Fs)
|
||||||
|
stateSourceObject.Load(26, &p.Gs)
|
||||||
|
}
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
state.Register((*PtraceRegs)(nil))
|
||||||
|
}
|
||||||
673
pkg/abi/linux/linux_arm64_abi_autogen_unsafe.go
Normal file
673
pkg/abi/linux/linux_arm64_abi_autogen_unsafe.go
Normal file
|
|
@ -0,0 +1,673 @@
|
||||||
|
// Automatically generated marshal implementation. See tools/go_marshal.
|
||||||
|
|
||||||
|
// If there are issues with build constraint aggregation, see
|
||||||
|
// tools/go_marshal/gomarshal/generator.go:writeHeader(). The constraints here
|
||||||
|
// come from the input set of files used to generate this file. This input set
|
||||||
|
// is filtered based on pre-defined file suffixes related to build constraints,
|
||||||
|
// see tools/defs.bzl:calculate_sets().
|
||||||
|
|
||||||
|
//go:build arm64 && arm64 && arm64 && arm64 && arm64
|
||||||
|
// +build arm64,arm64,arm64,arm64,arm64
|
||||||
|
|
||||||
|
package linux
|
||||||
|
|
||||||
|
import (
|
||||||
|
"io"
|
||||||
|
"reflect"
|
||||||
|
"runtime"
|
||||||
|
"unsafe"
|
||||||
|
|
||||||
|
"github.com/sagernet/gvisor/pkg/gohacks"
|
||||||
|
"github.com/sagernet/gvisor/pkg/hostarch"
|
||||||
|
"github.com/sagernet/gvisor/pkg/marshal"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Marshallable types used by this file.
|
||||||
|
var (
|
||||||
|
_ marshal.Marshallable = (*EpollEvent)(nil)
|
||||||
|
_ marshal.Marshallable = (*IPCPerm)(nil)
|
||||||
|
_ marshal.Marshallable = (*PtraceRegs)(nil)
|
||||||
|
_ marshal.Marshallable = (*SemidDS)(nil)
|
||||||
|
_ marshal.Marshallable = (*Stat)(nil)
|
||||||
|
_ marshal.Marshallable = (*TimeT)(nil)
|
||||||
|
_ marshal.Marshallable = (*Timespec)(nil)
|
||||||
|
)
|
||||||
|
|
||||||
|
// SizeBytes implements marshal.Marshallable.SizeBytes.
|
||||||
|
func (e *EpollEvent) SizeBytes() int {
|
||||||
|
return 8 +
|
||||||
|
4*2
|
||||||
|
}
|
||||||
|
|
||||||
|
// MarshalBytes implements marshal.Marshallable.MarshalBytes.
|
||||||
|
func (e *EpollEvent) MarshalBytes(dst []byte) []byte {
|
||||||
|
hostarch.ByteOrder.PutUint32(dst[:4], uint32(e.Events))
|
||||||
|
dst = dst[4:]
|
||||||
|
// Padding: dst[:sizeof(int32)] ~= int32(0)
|
||||||
|
dst = dst[4:]
|
||||||
|
for idx := 0; idx < 2; idx++ {
|
||||||
|
hostarch.ByteOrder.PutUint32(dst[:4], uint32(e.Data[idx]))
|
||||||
|
dst = dst[4:]
|
||||||
|
}
|
||||||
|
return dst
|
||||||
|
}
|
||||||
|
|
||||||
|
// UnmarshalBytes implements marshal.Marshallable.UnmarshalBytes.
|
||||||
|
func (e *EpollEvent) UnmarshalBytes(src []byte) []byte {
|
||||||
|
e.Events = uint32(hostarch.ByteOrder.Uint32(src[:4]))
|
||||||
|
src = src[4:]
|
||||||
|
// Padding: var _ int32 ~= src[:sizeof(int32)]
|
||||||
|
src = src[4:]
|
||||||
|
for idx := 0; idx < 2; idx++ {
|
||||||
|
e.Data[idx] = int32(hostarch.ByteOrder.Uint32(src[:4]))
|
||||||
|
src = src[4:]
|
||||||
|
}
|
||||||
|
return src
|
||||||
|
}
|
||||||
|
|
||||||
|
// Packed implements marshal.Marshallable.Packed.
|
||||||
|
//
|
||||||
|
//go:nosplit
|
||||||
|
func (e *EpollEvent) Packed() bool {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
// MarshalUnsafe implements marshal.Marshallable.MarshalUnsafe.
|
||||||
|
func (e *EpollEvent) MarshalUnsafe(dst []byte) []byte {
|
||||||
|
size := e.SizeBytes()
|
||||||
|
gohacks.Memmove(unsafe.Pointer(&dst[0]), unsafe.Pointer(e), uintptr(size))
|
||||||
|
return dst[size:]
|
||||||
|
}
|
||||||
|
|
||||||
|
// UnmarshalUnsafe implements marshal.Marshallable.UnmarshalUnsafe.
|
||||||
|
func (e *EpollEvent) UnmarshalUnsafe(src []byte) []byte {
|
||||||
|
size := e.SizeBytes()
|
||||||
|
gohacks.Memmove(unsafe.Pointer(e), unsafe.Pointer(&src[0]), uintptr(size))
|
||||||
|
return src[size:]
|
||||||
|
}
|
||||||
|
|
||||||
|
// CopyOutN implements marshal.Marshallable.CopyOutN.
|
||||||
|
func (e *EpollEvent) CopyOutN(cc marshal.CopyContext, addr hostarch.Addr, limit int) (int, error) {
|
||||||
|
// Construct a slice backed by dst's underlying memory.
|
||||||
|
var buf []byte
|
||||||
|
hdr := (*reflect.SliceHeader)(unsafe.Pointer(&buf))
|
||||||
|
hdr.Data = uintptr(gohacks.Noescape(unsafe.Pointer(e)))
|
||||||
|
hdr.Len = e.SizeBytes()
|
||||||
|
hdr.Cap = e.SizeBytes()
|
||||||
|
|
||||||
|
length, err := cc.CopyOutBytes(addr, buf[:limit]) // escapes: okay.
|
||||||
|
// Since we bypassed the compiler's escape analysis, indicate that e
|
||||||
|
// must live until the use above.
|
||||||
|
runtime.KeepAlive(e) // escapes: replaced by intrinsic.
|
||||||
|
return length, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// CopyOut implements marshal.Marshallable.CopyOut.
|
||||||
|
func (e *EpollEvent) CopyOut(cc marshal.CopyContext, addr hostarch.Addr) (int, error) {
|
||||||
|
return e.CopyOutN(cc, addr, e.SizeBytes())
|
||||||
|
}
|
||||||
|
|
||||||
|
// CopyInN implements marshal.Marshallable.CopyInN.
|
||||||
|
func (e *EpollEvent) CopyInN(cc marshal.CopyContext, addr hostarch.Addr, limit int) (int, error) {
|
||||||
|
// Construct a slice backed by dst's underlying memory.
|
||||||
|
var buf []byte
|
||||||
|
hdr := (*reflect.SliceHeader)(unsafe.Pointer(&buf))
|
||||||
|
hdr.Data = uintptr(gohacks.Noescape(unsafe.Pointer(e)))
|
||||||
|
hdr.Len = e.SizeBytes()
|
||||||
|
hdr.Cap = e.SizeBytes()
|
||||||
|
|
||||||
|
length, err := cc.CopyInBytes(addr, buf[:limit]) // escapes: okay.
|
||||||
|
// Since we bypassed the compiler's escape analysis, indicate that e
|
||||||
|
// must live until the use above.
|
||||||
|
runtime.KeepAlive(e) // escapes: replaced by intrinsic.
|
||||||
|
return length, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// CopyIn implements marshal.Marshallable.CopyIn.
|
||||||
|
func (e *EpollEvent) CopyIn(cc marshal.CopyContext, addr hostarch.Addr) (int, error) {
|
||||||
|
return e.CopyInN(cc, addr, e.SizeBytes())
|
||||||
|
}
|
||||||
|
|
||||||
|
// WriteTo implements io.WriterTo.WriteTo.
|
||||||
|
func (e *EpollEvent) WriteTo(writer io.Writer) (int64, error) {
|
||||||
|
// Construct a slice backed by dst's underlying memory.
|
||||||
|
var buf []byte
|
||||||
|
hdr := (*reflect.SliceHeader)(unsafe.Pointer(&buf))
|
||||||
|
hdr.Data = uintptr(gohacks.Noescape(unsafe.Pointer(e)))
|
||||||
|
hdr.Len = e.SizeBytes()
|
||||||
|
hdr.Cap = e.SizeBytes()
|
||||||
|
|
||||||
|
length, err := writer.Write(buf)
|
||||||
|
// Since we bypassed the compiler's escape analysis, indicate that e
|
||||||
|
// must live until the use above.
|
||||||
|
runtime.KeepAlive(e) // escapes: replaced by intrinsic.
|
||||||
|
return int64(length), err
|
||||||
|
}
|
||||||
|
|
||||||
|
// CopyEpollEventSliceIn copies in a slice of EpollEvent objects from the task's memory.
|
||||||
|
func CopyEpollEventSliceIn(cc marshal.CopyContext, addr hostarch.Addr, dst []EpollEvent) (int, error) {
|
||||||
|
count := len(dst)
|
||||||
|
if count == 0 {
|
||||||
|
return 0, nil
|
||||||
|
}
|
||||||
|
size := (*EpollEvent)(nil).SizeBytes()
|
||||||
|
|
||||||
|
ptr := unsafe.Pointer(&dst)
|
||||||
|
val := gohacks.Noescape(unsafe.Pointer((*reflect.SliceHeader)(ptr).Data))
|
||||||
|
|
||||||
|
// Construct a slice backed by dst's underlying memory.
|
||||||
|
var buf []byte
|
||||||
|
hdr := (*reflect.SliceHeader)(unsafe.Pointer(&buf))
|
||||||
|
hdr.Data = uintptr(val)
|
||||||
|
hdr.Len = size * count
|
||||||
|
hdr.Cap = size * count
|
||||||
|
|
||||||
|
length, err := cc.CopyInBytes(addr, buf)
|
||||||
|
// Since we bypassed the compiler's escape analysis, indicate that dst
|
||||||
|
// must live until the use above.
|
||||||
|
runtime.KeepAlive(dst) // escapes: replaced by intrinsic.
|
||||||
|
return length, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// CopyEpollEventSliceOut copies a slice of EpollEvent objects to the task's memory.
|
||||||
|
func CopyEpollEventSliceOut(cc marshal.CopyContext, addr hostarch.Addr, src []EpollEvent) (int, error) {
|
||||||
|
count := len(src)
|
||||||
|
if count == 0 {
|
||||||
|
return 0, nil
|
||||||
|
}
|
||||||
|
size := (*EpollEvent)(nil).SizeBytes()
|
||||||
|
|
||||||
|
ptr := unsafe.Pointer(&src)
|
||||||
|
val := gohacks.Noescape(unsafe.Pointer((*reflect.SliceHeader)(ptr).Data))
|
||||||
|
|
||||||
|
// Construct a slice backed by dst's underlying memory.
|
||||||
|
var buf []byte
|
||||||
|
hdr := (*reflect.SliceHeader)(unsafe.Pointer(&buf))
|
||||||
|
hdr.Data = uintptr(val)
|
||||||
|
hdr.Len = size * count
|
||||||
|
hdr.Cap = size * count
|
||||||
|
|
||||||
|
length, err := cc.CopyOutBytes(addr, buf)
|
||||||
|
// Since we bypassed the compiler's escape analysis, indicate that src
|
||||||
|
// must live until the use above.
|
||||||
|
runtime.KeepAlive(src) // escapes: replaced by intrinsic.
|
||||||
|
return length, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// MarshalUnsafeEpollEventSlice is like EpollEvent.MarshalUnsafe, but for a []EpollEvent.
|
||||||
|
func MarshalUnsafeEpollEventSlice(src []EpollEvent, dst []byte) []byte {
|
||||||
|
count := len(src)
|
||||||
|
if count == 0 {
|
||||||
|
return dst
|
||||||
|
}
|
||||||
|
|
||||||
|
size := (*EpollEvent)(nil).SizeBytes()
|
||||||
|
buf := dst[:size*count]
|
||||||
|
gohacks.Memmove(unsafe.Pointer(&buf[0]), unsafe.Pointer(&src[0]), uintptr(len(buf)))
|
||||||
|
return dst[size*count:]
|
||||||
|
}
|
||||||
|
|
||||||
|
// UnmarshalUnsafeEpollEventSlice is like EpollEvent.UnmarshalUnsafe, but for a []EpollEvent.
|
||||||
|
func UnmarshalUnsafeEpollEventSlice(dst []EpollEvent, src []byte) []byte {
|
||||||
|
count := len(dst)
|
||||||
|
if count == 0 {
|
||||||
|
return src
|
||||||
|
}
|
||||||
|
|
||||||
|
size := (*EpollEvent)(nil).SizeBytes()
|
||||||
|
buf := src[:size*count]
|
||||||
|
gohacks.Memmove(unsafe.Pointer(&dst[0]), unsafe.Pointer(&buf[0]), uintptr(len(buf)))
|
||||||
|
return src[size*count:]
|
||||||
|
}
|
||||||
|
|
||||||
|
// SizeBytes implements marshal.Marshallable.SizeBytes.
|
||||||
|
func (s *Stat) SizeBytes() int {
|
||||||
|
return 72 +
|
||||||
|
(*Timespec)(nil).SizeBytes() +
|
||||||
|
(*Timespec)(nil).SizeBytes() +
|
||||||
|
(*Timespec)(nil).SizeBytes() +
|
||||||
|
4*2
|
||||||
|
}
|
||||||
|
|
||||||
|
// MarshalBytes implements marshal.Marshallable.MarshalBytes.
|
||||||
|
func (s *Stat) MarshalBytes(dst []byte) []byte {
|
||||||
|
hostarch.ByteOrder.PutUint64(dst[:8], uint64(s.Dev))
|
||||||
|
dst = dst[8:]
|
||||||
|
hostarch.ByteOrder.PutUint64(dst[:8], uint64(s.Ino))
|
||||||
|
dst = dst[8:]
|
||||||
|
hostarch.ByteOrder.PutUint32(dst[:4], uint32(s.Mode))
|
||||||
|
dst = dst[4:]
|
||||||
|
hostarch.ByteOrder.PutUint32(dst[:4], uint32(s.Nlink))
|
||||||
|
dst = dst[4:]
|
||||||
|
hostarch.ByteOrder.PutUint32(dst[:4], uint32(s.UID))
|
||||||
|
dst = dst[4:]
|
||||||
|
hostarch.ByteOrder.PutUint32(dst[:4], uint32(s.GID))
|
||||||
|
dst = dst[4:]
|
||||||
|
hostarch.ByteOrder.PutUint64(dst[:8], uint64(s.Rdev))
|
||||||
|
dst = dst[8:]
|
||||||
|
// Padding: dst[:sizeof(uint64)] ~= uint64(0)
|
||||||
|
dst = dst[8:]
|
||||||
|
hostarch.ByteOrder.PutUint64(dst[:8], uint64(s.Size))
|
||||||
|
dst = dst[8:]
|
||||||
|
hostarch.ByteOrder.PutUint32(dst[:4], uint32(s.Blksize))
|
||||||
|
dst = dst[4:]
|
||||||
|
// Padding: dst[:sizeof(int32)] ~= int32(0)
|
||||||
|
dst = dst[4:]
|
||||||
|
hostarch.ByteOrder.PutUint64(dst[:8], uint64(s.Blocks))
|
||||||
|
dst = dst[8:]
|
||||||
|
dst = s.ATime.MarshalUnsafe(dst)
|
||||||
|
dst = s.MTime.MarshalUnsafe(dst)
|
||||||
|
dst = s.CTime.MarshalUnsafe(dst)
|
||||||
|
// Padding: dst[:sizeof(int32)*2] ~= [2]int32{0}
|
||||||
|
dst = dst[4*(2):]
|
||||||
|
return dst
|
||||||
|
}
|
||||||
|
|
||||||
|
// UnmarshalBytes implements marshal.Marshallable.UnmarshalBytes.
|
||||||
|
func (s *Stat) UnmarshalBytes(src []byte) []byte {
|
||||||
|
s.Dev = uint64(hostarch.ByteOrder.Uint64(src[:8]))
|
||||||
|
src = src[8:]
|
||||||
|
s.Ino = uint64(hostarch.ByteOrder.Uint64(src[:8]))
|
||||||
|
src = src[8:]
|
||||||
|
s.Mode = uint32(hostarch.ByteOrder.Uint32(src[:4]))
|
||||||
|
src = src[4:]
|
||||||
|
s.Nlink = uint32(hostarch.ByteOrder.Uint32(src[:4]))
|
||||||
|
src = src[4:]
|
||||||
|
s.UID = uint32(hostarch.ByteOrder.Uint32(src[:4]))
|
||||||
|
src = src[4:]
|
||||||
|
s.GID = uint32(hostarch.ByteOrder.Uint32(src[:4]))
|
||||||
|
src = src[4:]
|
||||||
|
s.Rdev = uint64(hostarch.ByteOrder.Uint64(src[:8]))
|
||||||
|
src = src[8:]
|
||||||
|
// Padding: var _ uint64 ~= src[:sizeof(uint64)]
|
||||||
|
src = src[8:]
|
||||||
|
s.Size = int64(hostarch.ByteOrder.Uint64(src[:8]))
|
||||||
|
src = src[8:]
|
||||||
|
s.Blksize = int32(hostarch.ByteOrder.Uint32(src[:4]))
|
||||||
|
src = src[4:]
|
||||||
|
// Padding: var _ int32 ~= src[:sizeof(int32)]
|
||||||
|
src = src[4:]
|
||||||
|
s.Blocks = int64(hostarch.ByteOrder.Uint64(src[:8]))
|
||||||
|
src = src[8:]
|
||||||
|
src = s.ATime.UnmarshalUnsafe(src)
|
||||||
|
src = s.MTime.UnmarshalUnsafe(src)
|
||||||
|
src = s.CTime.UnmarshalUnsafe(src)
|
||||||
|
// Padding: ~ copy([2]int32(s._), src[:sizeof(int32)*2])
|
||||||
|
src = src[4*(2):]
|
||||||
|
return src
|
||||||
|
}
|
||||||
|
|
||||||
|
// Packed implements marshal.Marshallable.Packed.
|
||||||
|
//
|
||||||
|
//go:nosplit
|
||||||
|
func (s *Stat) Packed() bool {
|
||||||
|
return s.ATime.Packed() && s.CTime.Packed() && s.MTime.Packed()
|
||||||
|
}
|
||||||
|
|
||||||
|
// MarshalUnsafe implements marshal.Marshallable.MarshalUnsafe.
|
||||||
|
func (s *Stat) MarshalUnsafe(dst []byte) []byte {
|
||||||
|
if s.ATime.Packed() && s.CTime.Packed() && s.MTime.Packed() {
|
||||||
|
size := s.SizeBytes()
|
||||||
|
gohacks.Memmove(unsafe.Pointer(&dst[0]), unsafe.Pointer(s), uintptr(size))
|
||||||
|
return dst[size:]
|
||||||
|
}
|
||||||
|
// Type Stat doesn't have a packed layout in memory, fallback to MarshalBytes.
|
||||||
|
return s.MarshalBytes(dst)
|
||||||
|
}
|
||||||
|
|
||||||
|
// UnmarshalUnsafe implements marshal.Marshallable.UnmarshalUnsafe.
|
||||||
|
func (s *Stat) UnmarshalUnsafe(src []byte) []byte {
|
||||||
|
if s.ATime.Packed() && s.CTime.Packed() && s.MTime.Packed() {
|
||||||
|
size := s.SizeBytes()
|
||||||
|
gohacks.Memmove(unsafe.Pointer(s), unsafe.Pointer(&src[0]), uintptr(size))
|
||||||
|
return src[size:]
|
||||||
|
}
|
||||||
|
// Type Stat doesn't have a packed layout in memory, fallback to UnmarshalBytes.
|
||||||
|
return s.UnmarshalBytes(src)
|
||||||
|
}
|
||||||
|
|
||||||
|
// CopyOutN implements marshal.Marshallable.CopyOutN.
|
||||||
|
func (s *Stat) CopyOutN(cc marshal.CopyContext, addr hostarch.Addr, limit int) (int, error) {
|
||||||
|
if !s.ATime.Packed() && s.CTime.Packed() && s.MTime.Packed() {
|
||||||
|
// Type Stat doesn't have a packed layout in memory, fall back to MarshalBytes.
|
||||||
|
buf := cc.CopyScratchBuffer(s.SizeBytes()) // escapes: okay.
|
||||||
|
s.MarshalBytes(buf) // escapes: fallback.
|
||||||
|
return cc.CopyOutBytes(addr, buf[:limit]) // escapes: okay.
|
||||||
|
}
|
||||||
|
|
||||||
|
// Construct a slice backed by dst's underlying memory.
|
||||||
|
var buf []byte
|
||||||
|
hdr := (*reflect.SliceHeader)(unsafe.Pointer(&buf))
|
||||||
|
hdr.Data = uintptr(gohacks.Noescape(unsafe.Pointer(s)))
|
||||||
|
hdr.Len = s.SizeBytes()
|
||||||
|
hdr.Cap = s.SizeBytes()
|
||||||
|
|
||||||
|
length, err := cc.CopyOutBytes(addr, buf[:limit]) // escapes: okay.
|
||||||
|
// Since we bypassed the compiler's escape analysis, indicate that s
|
||||||
|
// must live until the use above.
|
||||||
|
runtime.KeepAlive(s) // escapes: replaced by intrinsic.
|
||||||
|
return length, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// CopyOut implements marshal.Marshallable.CopyOut.
|
||||||
|
func (s *Stat) CopyOut(cc marshal.CopyContext, addr hostarch.Addr) (int, error) {
|
||||||
|
return s.CopyOutN(cc, addr, s.SizeBytes())
|
||||||
|
}
|
||||||
|
|
||||||
|
// CopyInN implements marshal.Marshallable.CopyInN.
|
||||||
|
func (s *Stat) CopyInN(cc marshal.CopyContext, addr hostarch.Addr, limit int) (int, error) {
|
||||||
|
if !s.ATime.Packed() && s.CTime.Packed() && s.MTime.Packed() {
|
||||||
|
// Type Stat doesn't have a packed layout in memory, fall back to UnmarshalBytes.
|
||||||
|
buf := cc.CopyScratchBuffer(s.SizeBytes()) // escapes: okay.
|
||||||
|
length, err := cc.CopyInBytes(addr, buf[:limit]) // escapes: okay.
|
||||||
|
// Unmarshal unconditionally. If we had a short copy-in, this results in a
|
||||||
|
// partially unmarshalled struct.
|
||||||
|
s.UnmarshalBytes(buf) // escapes: fallback.
|
||||||
|
return length, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Construct a slice backed by dst's underlying memory.
|
||||||
|
var buf []byte
|
||||||
|
hdr := (*reflect.SliceHeader)(unsafe.Pointer(&buf))
|
||||||
|
hdr.Data = uintptr(gohacks.Noescape(unsafe.Pointer(s)))
|
||||||
|
hdr.Len = s.SizeBytes()
|
||||||
|
hdr.Cap = s.SizeBytes()
|
||||||
|
|
||||||
|
length, err := cc.CopyInBytes(addr, buf[:limit]) // escapes: okay.
|
||||||
|
// Since we bypassed the compiler's escape analysis, indicate that s
|
||||||
|
// must live until the use above.
|
||||||
|
runtime.KeepAlive(s) // escapes: replaced by intrinsic.
|
||||||
|
return length, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// CopyIn implements marshal.Marshallable.CopyIn.
|
||||||
|
func (s *Stat) CopyIn(cc marshal.CopyContext, addr hostarch.Addr) (int, error) {
|
||||||
|
return s.CopyInN(cc, addr, s.SizeBytes())
|
||||||
|
}
|
||||||
|
|
||||||
|
// WriteTo implements io.WriterTo.WriteTo.
|
||||||
|
func (s *Stat) WriteTo(writer io.Writer) (int64, error) {
|
||||||
|
if !s.ATime.Packed() && s.CTime.Packed() && s.MTime.Packed() {
|
||||||
|
// Type Stat doesn't have a packed layout in memory, fall back to MarshalBytes.
|
||||||
|
buf := make([]byte, s.SizeBytes())
|
||||||
|
s.MarshalBytes(buf)
|
||||||
|
length, err := writer.Write(buf)
|
||||||
|
return int64(length), err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Construct a slice backed by dst's underlying memory.
|
||||||
|
var buf []byte
|
||||||
|
hdr := (*reflect.SliceHeader)(unsafe.Pointer(&buf))
|
||||||
|
hdr.Data = uintptr(gohacks.Noescape(unsafe.Pointer(s)))
|
||||||
|
hdr.Len = s.SizeBytes()
|
||||||
|
hdr.Cap = s.SizeBytes()
|
||||||
|
|
||||||
|
length, err := writer.Write(buf)
|
||||||
|
// Since we bypassed the compiler's escape analysis, indicate that s
|
||||||
|
// must live until the use above.
|
||||||
|
runtime.KeepAlive(s) // escapes: replaced by intrinsic.
|
||||||
|
return int64(length), err
|
||||||
|
}
|
||||||
|
|
||||||
|
// SizeBytes implements marshal.Marshallable.SizeBytes.
|
||||||
|
func (p *PtraceRegs) SizeBytes() int {
|
||||||
|
return 24 +
|
||||||
|
8*31
|
||||||
|
}
|
||||||
|
|
||||||
|
// MarshalBytes implements marshal.Marshallable.MarshalBytes.
|
||||||
|
func (p *PtraceRegs) MarshalBytes(dst []byte) []byte {
|
||||||
|
for idx := 0; idx < 31; idx++ {
|
||||||
|
hostarch.ByteOrder.PutUint64(dst[:8], uint64(p.Regs[idx]))
|
||||||
|
dst = dst[8:]
|
||||||
|
}
|
||||||
|
hostarch.ByteOrder.PutUint64(dst[:8], uint64(p.Sp))
|
||||||
|
dst = dst[8:]
|
||||||
|
hostarch.ByteOrder.PutUint64(dst[:8], uint64(p.Pc))
|
||||||
|
dst = dst[8:]
|
||||||
|
hostarch.ByteOrder.PutUint64(dst[:8], uint64(p.Pstate))
|
||||||
|
dst = dst[8:]
|
||||||
|
return dst
|
||||||
|
}
|
||||||
|
|
||||||
|
// UnmarshalBytes implements marshal.Marshallable.UnmarshalBytes.
|
||||||
|
func (p *PtraceRegs) UnmarshalBytes(src []byte) []byte {
|
||||||
|
for idx := 0; idx < 31; idx++ {
|
||||||
|
p.Regs[idx] = uint64(hostarch.ByteOrder.Uint64(src[:8]))
|
||||||
|
src = src[8:]
|
||||||
|
}
|
||||||
|
p.Sp = uint64(hostarch.ByteOrder.Uint64(src[:8]))
|
||||||
|
src = src[8:]
|
||||||
|
p.Pc = uint64(hostarch.ByteOrder.Uint64(src[:8]))
|
||||||
|
src = src[8:]
|
||||||
|
p.Pstate = uint64(hostarch.ByteOrder.Uint64(src[:8]))
|
||||||
|
src = src[8:]
|
||||||
|
return src
|
||||||
|
}
|
||||||
|
|
||||||
|
// Packed implements marshal.Marshallable.Packed.
|
||||||
|
//
|
||||||
|
//go:nosplit
|
||||||
|
func (p *PtraceRegs) Packed() bool {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
// MarshalUnsafe implements marshal.Marshallable.MarshalUnsafe.
|
||||||
|
func (p *PtraceRegs) MarshalUnsafe(dst []byte) []byte {
|
||||||
|
size := p.SizeBytes()
|
||||||
|
gohacks.Memmove(unsafe.Pointer(&dst[0]), unsafe.Pointer(p), uintptr(size))
|
||||||
|
return dst[size:]
|
||||||
|
}
|
||||||
|
|
||||||
|
// UnmarshalUnsafe implements marshal.Marshallable.UnmarshalUnsafe.
|
||||||
|
func (p *PtraceRegs) UnmarshalUnsafe(src []byte) []byte {
|
||||||
|
size := p.SizeBytes()
|
||||||
|
gohacks.Memmove(unsafe.Pointer(p), unsafe.Pointer(&src[0]), uintptr(size))
|
||||||
|
return src[size:]
|
||||||
|
}
|
||||||
|
|
||||||
|
// CopyOutN implements marshal.Marshallable.CopyOutN.
|
||||||
|
func (p *PtraceRegs) CopyOutN(cc marshal.CopyContext, addr hostarch.Addr, limit int) (int, error) {
|
||||||
|
// Construct a slice backed by dst's underlying memory.
|
||||||
|
var buf []byte
|
||||||
|
hdr := (*reflect.SliceHeader)(unsafe.Pointer(&buf))
|
||||||
|
hdr.Data = uintptr(gohacks.Noescape(unsafe.Pointer(p)))
|
||||||
|
hdr.Len = p.SizeBytes()
|
||||||
|
hdr.Cap = p.SizeBytes()
|
||||||
|
|
||||||
|
length, err := cc.CopyOutBytes(addr, buf[:limit]) // escapes: okay.
|
||||||
|
// Since we bypassed the compiler's escape analysis, indicate that p
|
||||||
|
// must live until the use above.
|
||||||
|
runtime.KeepAlive(p) // escapes: replaced by intrinsic.
|
||||||
|
return length, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// CopyOut implements marshal.Marshallable.CopyOut.
|
||||||
|
func (p *PtraceRegs) CopyOut(cc marshal.CopyContext, addr hostarch.Addr) (int, error) {
|
||||||
|
return p.CopyOutN(cc, addr, p.SizeBytes())
|
||||||
|
}
|
||||||
|
|
||||||
|
// CopyInN implements marshal.Marshallable.CopyInN.
|
||||||
|
func (p *PtraceRegs) CopyInN(cc marshal.CopyContext, addr hostarch.Addr, limit int) (int, error) {
|
||||||
|
// Construct a slice backed by dst's underlying memory.
|
||||||
|
var buf []byte
|
||||||
|
hdr := (*reflect.SliceHeader)(unsafe.Pointer(&buf))
|
||||||
|
hdr.Data = uintptr(gohacks.Noescape(unsafe.Pointer(p)))
|
||||||
|
hdr.Len = p.SizeBytes()
|
||||||
|
hdr.Cap = p.SizeBytes()
|
||||||
|
|
||||||
|
length, err := cc.CopyInBytes(addr, buf[:limit]) // escapes: okay.
|
||||||
|
// Since we bypassed the compiler's escape analysis, indicate that p
|
||||||
|
// must live until the use above.
|
||||||
|
runtime.KeepAlive(p) // escapes: replaced by intrinsic.
|
||||||
|
return length, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// CopyIn implements marshal.Marshallable.CopyIn.
|
||||||
|
func (p *PtraceRegs) CopyIn(cc marshal.CopyContext, addr hostarch.Addr) (int, error) {
|
||||||
|
return p.CopyInN(cc, addr, p.SizeBytes())
|
||||||
|
}
|
||||||
|
|
||||||
|
// WriteTo implements io.WriterTo.WriteTo.
|
||||||
|
func (p *PtraceRegs) WriteTo(writer io.Writer) (int64, error) {
|
||||||
|
// Construct a slice backed by dst's underlying memory.
|
||||||
|
var buf []byte
|
||||||
|
hdr := (*reflect.SliceHeader)(unsafe.Pointer(&buf))
|
||||||
|
hdr.Data = uintptr(gohacks.Noescape(unsafe.Pointer(p)))
|
||||||
|
hdr.Len = p.SizeBytes()
|
||||||
|
hdr.Cap = p.SizeBytes()
|
||||||
|
|
||||||
|
length, err := writer.Write(buf)
|
||||||
|
// Since we bypassed the compiler's escape analysis, indicate that p
|
||||||
|
// must live until the use above.
|
||||||
|
runtime.KeepAlive(p) // escapes: replaced by intrinsic.
|
||||||
|
return int64(length), err
|
||||||
|
}
|
||||||
|
|
||||||
|
// SizeBytes implements marshal.Marshallable.SizeBytes.
|
||||||
|
func (s *SemidDS) SizeBytes() int {
|
||||||
|
return 24 +
|
||||||
|
(*IPCPerm)(nil).SizeBytes() +
|
||||||
|
(*TimeT)(nil).SizeBytes() +
|
||||||
|
(*TimeT)(nil).SizeBytes()
|
||||||
|
}
|
||||||
|
|
||||||
|
// MarshalBytes implements marshal.Marshallable.MarshalBytes.
|
||||||
|
func (s *SemidDS) MarshalBytes(dst []byte) []byte {
|
||||||
|
dst = s.SemPerm.MarshalUnsafe(dst)
|
||||||
|
dst = s.SemOTime.MarshalUnsafe(dst)
|
||||||
|
dst = s.SemCTime.MarshalUnsafe(dst)
|
||||||
|
hostarch.ByteOrder.PutUint64(dst[:8], uint64(s.SemNSems))
|
||||||
|
dst = dst[8:]
|
||||||
|
hostarch.ByteOrder.PutUint64(dst[:8], uint64(s.unused3))
|
||||||
|
dst = dst[8:]
|
||||||
|
hostarch.ByteOrder.PutUint64(dst[:8], uint64(s.unused4))
|
||||||
|
dst = dst[8:]
|
||||||
|
return dst
|
||||||
|
}
|
||||||
|
|
||||||
|
// UnmarshalBytes implements marshal.Marshallable.UnmarshalBytes.
|
||||||
|
func (s *SemidDS) UnmarshalBytes(src []byte) []byte {
|
||||||
|
src = s.SemPerm.UnmarshalUnsafe(src)
|
||||||
|
src = s.SemOTime.UnmarshalUnsafe(src)
|
||||||
|
src = s.SemCTime.UnmarshalUnsafe(src)
|
||||||
|
s.SemNSems = uint64(hostarch.ByteOrder.Uint64(src[:8]))
|
||||||
|
src = src[8:]
|
||||||
|
s.unused3 = uint64(hostarch.ByteOrder.Uint64(src[:8]))
|
||||||
|
src = src[8:]
|
||||||
|
s.unused4 = uint64(hostarch.ByteOrder.Uint64(src[:8]))
|
||||||
|
src = src[8:]
|
||||||
|
return src
|
||||||
|
}
|
||||||
|
|
||||||
|
// Packed implements marshal.Marshallable.Packed.
|
||||||
|
//
|
||||||
|
//go:nosplit
|
||||||
|
func (s *SemidDS) Packed() bool {
|
||||||
|
return s.SemCTime.Packed() && s.SemOTime.Packed() && s.SemPerm.Packed()
|
||||||
|
}
|
||||||
|
|
||||||
|
// MarshalUnsafe implements marshal.Marshallable.MarshalUnsafe.
|
||||||
|
func (s *SemidDS) MarshalUnsafe(dst []byte) []byte {
|
||||||
|
if s.SemCTime.Packed() && s.SemOTime.Packed() && s.SemPerm.Packed() {
|
||||||
|
size := s.SizeBytes()
|
||||||
|
gohacks.Memmove(unsafe.Pointer(&dst[0]), unsafe.Pointer(s), uintptr(size))
|
||||||
|
return dst[size:]
|
||||||
|
}
|
||||||
|
// Type SemidDS doesn't have a packed layout in memory, fallback to MarshalBytes.
|
||||||
|
return s.MarshalBytes(dst)
|
||||||
|
}
|
||||||
|
|
||||||
|
// UnmarshalUnsafe implements marshal.Marshallable.UnmarshalUnsafe.
|
||||||
|
func (s *SemidDS) UnmarshalUnsafe(src []byte) []byte {
|
||||||
|
if s.SemCTime.Packed() && s.SemOTime.Packed() && s.SemPerm.Packed() {
|
||||||
|
size := s.SizeBytes()
|
||||||
|
gohacks.Memmove(unsafe.Pointer(s), unsafe.Pointer(&src[0]), uintptr(size))
|
||||||
|
return src[size:]
|
||||||
|
}
|
||||||
|
// Type SemidDS doesn't have a packed layout in memory, fallback to UnmarshalBytes.
|
||||||
|
return s.UnmarshalBytes(src)
|
||||||
|
}
|
||||||
|
|
||||||
|
// CopyOutN implements marshal.Marshallable.CopyOutN.
|
||||||
|
func (s *SemidDS) CopyOutN(cc marshal.CopyContext, addr hostarch.Addr, limit int) (int, error) {
|
||||||
|
if !s.SemCTime.Packed() && s.SemOTime.Packed() && s.SemPerm.Packed() {
|
||||||
|
// Type SemidDS doesn't have a packed layout in memory, fall back to MarshalBytes.
|
||||||
|
buf := cc.CopyScratchBuffer(s.SizeBytes()) // escapes: okay.
|
||||||
|
s.MarshalBytes(buf) // escapes: fallback.
|
||||||
|
return cc.CopyOutBytes(addr, buf[:limit]) // escapes: okay.
|
||||||
|
}
|
||||||
|
|
||||||
|
// Construct a slice backed by dst's underlying memory.
|
||||||
|
var buf []byte
|
||||||
|
hdr := (*reflect.SliceHeader)(unsafe.Pointer(&buf))
|
||||||
|
hdr.Data = uintptr(gohacks.Noescape(unsafe.Pointer(s)))
|
||||||
|
hdr.Len = s.SizeBytes()
|
||||||
|
hdr.Cap = s.SizeBytes()
|
||||||
|
|
||||||
|
length, err := cc.CopyOutBytes(addr, buf[:limit]) // escapes: okay.
|
||||||
|
// Since we bypassed the compiler's escape analysis, indicate that s
|
||||||
|
// must live until the use above.
|
||||||
|
runtime.KeepAlive(s) // escapes: replaced by intrinsic.
|
||||||
|
return length, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// CopyOut implements marshal.Marshallable.CopyOut.
|
||||||
|
func (s *SemidDS) CopyOut(cc marshal.CopyContext, addr hostarch.Addr) (int, error) {
|
||||||
|
return s.CopyOutN(cc, addr, s.SizeBytes())
|
||||||
|
}
|
||||||
|
|
||||||
|
// CopyInN implements marshal.Marshallable.CopyInN.
|
||||||
|
func (s *SemidDS) CopyInN(cc marshal.CopyContext, addr hostarch.Addr, limit int) (int, error) {
|
||||||
|
if !s.SemCTime.Packed() && s.SemOTime.Packed() && s.SemPerm.Packed() {
|
||||||
|
// Type SemidDS doesn't have a packed layout in memory, fall back to UnmarshalBytes.
|
||||||
|
buf := cc.CopyScratchBuffer(s.SizeBytes()) // escapes: okay.
|
||||||
|
length, err := cc.CopyInBytes(addr, buf[:limit]) // escapes: okay.
|
||||||
|
// Unmarshal unconditionally. If we had a short copy-in, this results in a
|
||||||
|
// partially unmarshalled struct.
|
||||||
|
s.UnmarshalBytes(buf) // escapes: fallback.
|
||||||
|
return length, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Construct a slice backed by dst's underlying memory.
|
||||||
|
var buf []byte
|
||||||
|
hdr := (*reflect.SliceHeader)(unsafe.Pointer(&buf))
|
||||||
|
hdr.Data = uintptr(gohacks.Noescape(unsafe.Pointer(s)))
|
||||||
|
hdr.Len = s.SizeBytes()
|
||||||
|
hdr.Cap = s.SizeBytes()
|
||||||
|
|
||||||
|
length, err := cc.CopyInBytes(addr, buf[:limit]) // escapes: okay.
|
||||||
|
// Since we bypassed the compiler's escape analysis, indicate that s
|
||||||
|
// must live until the use above.
|
||||||
|
runtime.KeepAlive(s) // escapes: replaced by intrinsic.
|
||||||
|
return length, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// CopyIn implements marshal.Marshallable.CopyIn.
|
||||||
|
func (s *SemidDS) CopyIn(cc marshal.CopyContext, addr hostarch.Addr) (int, error) {
|
||||||
|
return s.CopyInN(cc, addr, s.SizeBytes())
|
||||||
|
}
|
||||||
|
|
||||||
|
// WriteTo implements io.WriterTo.WriteTo.
|
||||||
|
func (s *SemidDS) WriteTo(writer io.Writer) (int64, error) {
|
||||||
|
if !s.SemCTime.Packed() && s.SemOTime.Packed() && s.SemPerm.Packed() {
|
||||||
|
// Type SemidDS doesn't have a packed layout in memory, fall back to MarshalBytes.
|
||||||
|
buf := make([]byte, s.SizeBytes())
|
||||||
|
s.MarshalBytes(buf)
|
||||||
|
length, err := writer.Write(buf)
|
||||||
|
return int64(length), err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Construct a slice backed by dst's underlying memory.
|
||||||
|
var buf []byte
|
||||||
|
hdr := (*reflect.SliceHeader)(unsafe.Pointer(&buf))
|
||||||
|
hdr.Data = uintptr(gohacks.Noescape(unsafe.Pointer(s)))
|
||||||
|
hdr.Len = s.SizeBytes()
|
||||||
|
hdr.Cap = s.SizeBytes()
|
||||||
|
|
||||||
|
length, err := writer.Write(buf)
|
||||||
|
// Since we bypassed the compiler's escape analysis, indicate that s
|
||||||
|
// must live until the use above.
|
||||||
|
runtime.KeepAlive(s) // escapes: replaced by intrinsic.
|
||||||
|
return int64(length), err
|
||||||
|
}
|
||||||
50
pkg/abi/linux/linux_arm64_state_autogen.go
Normal file
50
pkg/abi/linux/linux_arm64_state_autogen.go
Normal file
|
|
@ -0,0 +1,50 @@
|
||||||
|
// automatically generated by stateify.
|
||||||
|
|
||||||
|
//go:build arm64 && arm64 && arm64 && arm64 && arm64
|
||||||
|
// +build arm64,arm64,arm64,arm64,arm64
|
||||||
|
|
||||||
|
package linux
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
|
||||||
|
"github.com/sagernet/gvisor/pkg/state"
|
||||||
|
)
|
||||||
|
|
||||||
|
func (p *PtraceRegs) StateTypeName() string {
|
||||||
|
return "pkg/abi/linux.PtraceRegs"
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *PtraceRegs) StateFields() []string {
|
||||||
|
return []string{
|
||||||
|
"Regs",
|
||||||
|
"Sp",
|
||||||
|
"Pc",
|
||||||
|
"Pstate",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *PtraceRegs) beforeSave() {}
|
||||||
|
|
||||||
|
// +checklocksignore
|
||||||
|
func (p *PtraceRegs) StateSave(stateSinkObject state.Sink) {
|
||||||
|
p.beforeSave()
|
||||||
|
stateSinkObject.Save(0, &p.Regs)
|
||||||
|
stateSinkObject.Save(1, &p.Sp)
|
||||||
|
stateSinkObject.Save(2, &p.Pc)
|
||||||
|
stateSinkObject.Save(3, &p.Pstate)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *PtraceRegs) afterLoad(context.Context) {}
|
||||||
|
|
||||||
|
// +checklocksignore
|
||||||
|
func (p *PtraceRegs) StateLoad(ctx context.Context, stateSourceObject state.Source) {
|
||||||
|
stateSourceObject.Load(0, &p.Regs)
|
||||||
|
stateSourceObject.Load(1, &p.Sp)
|
||||||
|
stateSourceObject.Load(2, &p.Pc)
|
||||||
|
stateSourceObject.Load(3, &p.Pstate)
|
||||||
|
}
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
state.Register((*PtraceRegs)(nil))
|
||||||
|
}
|
||||||
599
pkg/abi/linux/linux_state_autogen.go
Normal file
599
pkg/abi/linux/linux_state_autogen.go
Normal file
|
|
@ -0,0 +1,599 @@
|
||||||
|
// automatically generated by stateify.
|
||||||
|
|
||||||
|
package linux
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
|
||||||
|
"github.com/sagernet/gvisor/pkg/state"
|
||||||
|
)
|
||||||
|
|
||||||
|
func (i *IOEvent) StateTypeName() string {
|
||||||
|
return "pkg/abi/linux.IOEvent"
|
||||||
|
}
|
||||||
|
|
||||||
|
func (i *IOEvent) StateFields() []string {
|
||||||
|
return []string{
|
||||||
|
"Data",
|
||||||
|
"Obj",
|
||||||
|
"Result",
|
||||||
|
"Result2",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (i *IOEvent) beforeSave() {}
|
||||||
|
|
||||||
|
// +checklocksignore
|
||||||
|
func (i *IOEvent) StateSave(stateSinkObject state.Sink) {
|
||||||
|
i.beforeSave()
|
||||||
|
stateSinkObject.Save(0, &i.Data)
|
||||||
|
stateSinkObject.Save(1, &i.Obj)
|
||||||
|
stateSinkObject.Save(2, &i.Result)
|
||||||
|
stateSinkObject.Save(3, &i.Result2)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (i *IOEvent) afterLoad(context.Context) {}
|
||||||
|
|
||||||
|
// +checklocksignore
|
||||||
|
func (i *IOEvent) StateLoad(ctx context.Context, stateSourceObject state.Source) {
|
||||||
|
stateSourceObject.Load(0, &i.Data)
|
||||||
|
stateSourceObject.Load(1, &i.Obj)
|
||||||
|
stateSourceObject.Load(2, &i.Result)
|
||||||
|
stateSourceObject.Load(3, &i.Result2)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (b *BPFInstruction) StateTypeName() string {
|
||||||
|
return "pkg/abi/linux.BPFInstruction"
|
||||||
|
}
|
||||||
|
|
||||||
|
func (b *BPFInstruction) StateFields() []string {
|
||||||
|
return []string{
|
||||||
|
"OpCode",
|
||||||
|
"JumpIfTrue",
|
||||||
|
"JumpIfFalse",
|
||||||
|
"K",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (b *BPFInstruction) beforeSave() {}
|
||||||
|
|
||||||
|
// +checklocksignore
|
||||||
|
func (b *BPFInstruction) StateSave(stateSinkObject state.Sink) {
|
||||||
|
b.beforeSave()
|
||||||
|
stateSinkObject.Save(0, &b.OpCode)
|
||||||
|
stateSinkObject.Save(1, &b.JumpIfTrue)
|
||||||
|
stateSinkObject.Save(2, &b.JumpIfFalse)
|
||||||
|
stateSinkObject.Save(3, &b.K)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (b *BPFInstruction) afterLoad(context.Context) {}
|
||||||
|
|
||||||
|
// +checklocksignore
|
||||||
|
func (b *BPFInstruction) StateLoad(ctx context.Context, stateSourceObject state.Source) {
|
||||||
|
stateSourceObject.Load(0, &b.OpCode)
|
||||||
|
stateSourceObject.Load(1, &b.JumpIfTrue)
|
||||||
|
stateSourceObject.Load(2, &b.JumpIfFalse)
|
||||||
|
stateSourceObject.Load(3, &b.K)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *FUSEHeaderIn) StateTypeName() string {
|
||||||
|
return "pkg/abi/linux.FUSEHeaderIn"
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *FUSEHeaderIn) StateFields() []string {
|
||||||
|
return []string{
|
||||||
|
"Len",
|
||||||
|
"Opcode",
|
||||||
|
"Unique",
|
||||||
|
"NodeID",
|
||||||
|
"UID",
|
||||||
|
"GID",
|
||||||
|
"PID",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *FUSEHeaderIn) beforeSave() {}
|
||||||
|
|
||||||
|
// +checklocksignore
|
||||||
|
func (f *FUSEHeaderIn) StateSave(stateSinkObject state.Sink) {
|
||||||
|
f.beforeSave()
|
||||||
|
stateSinkObject.Save(0, &f.Len)
|
||||||
|
stateSinkObject.Save(1, &f.Opcode)
|
||||||
|
stateSinkObject.Save(2, &f.Unique)
|
||||||
|
stateSinkObject.Save(3, &f.NodeID)
|
||||||
|
stateSinkObject.Save(4, &f.UID)
|
||||||
|
stateSinkObject.Save(5, &f.GID)
|
||||||
|
stateSinkObject.Save(6, &f.PID)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *FUSEHeaderIn) afterLoad(context.Context) {}
|
||||||
|
|
||||||
|
// +checklocksignore
|
||||||
|
func (f *FUSEHeaderIn) StateLoad(ctx context.Context, stateSourceObject state.Source) {
|
||||||
|
stateSourceObject.Load(0, &f.Len)
|
||||||
|
stateSourceObject.Load(1, &f.Opcode)
|
||||||
|
stateSourceObject.Load(2, &f.Unique)
|
||||||
|
stateSourceObject.Load(3, &f.NodeID)
|
||||||
|
stateSourceObject.Load(4, &f.UID)
|
||||||
|
stateSourceObject.Load(5, &f.GID)
|
||||||
|
stateSourceObject.Load(6, &f.PID)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *FUSEHeaderOut) StateTypeName() string {
|
||||||
|
return "pkg/abi/linux.FUSEHeaderOut"
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *FUSEHeaderOut) StateFields() []string {
|
||||||
|
return []string{
|
||||||
|
"Len",
|
||||||
|
"Error",
|
||||||
|
"Unique",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *FUSEHeaderOut) beforeSave() {}
|
||||||
|
|
||||||
|
// +checklocksignore
|
||||||
|
func (f *FUSEHeaderOut) StateSave(stateSinkObject state.Sink) {
|
||||||
|
f.beforeSave()
|
||||||
|
stateSinkObject.Save(0, &f.Len)
|
||||||
|
stateSinkObject.Save(1, &f.Error)
|
||||||
|
stateSinkObject.Save(2, &f.Unique)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *FUSEHeaderOut) afterLoad(context.Context) {}
|
||||||
|
|
||||||
|
// +checklocksignore
|
||||||
|
func (f *FUSEHeaderOut) StateLoad(ctx context.Context, stateSourceObject state.Source) {
|
||||||
|
stateSourceObject.Load(0, &f.Len)
|
||||||
|
stateSourceObject.Load(1, &f.Error)
|
||||||
|
stateSourceObject.Load(2, &f.Unique)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (i *IOUringCqe) StateTypeName() string {
|
||||||
|
return "pkg/abi/linux.IOUringCqe"
|
||||||
|
}
|
||||||
|
|
||||||
|
func (i *IOUringCqe) StateFields() []string {
|
||||||
|
return []string{
|
||||||
|
"UserData",
|
||||||
|
"Res",
|
||||||
|
"Flags",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (i *IOUringCqe) beforeSave() {}
|
||||||
|
|
||||||
|
// +checklocksignore
|
||||||
|
func (i *IOUringCqe) StateSave(stateSinkObject state.Sink) {
|
||||||
|
i.beforeSave()
|
||||||
|
stateSinkObject.Save(0, &i.UserData)
|
||||||
|
stateSinkObject.Save(1, &i.Res)
|
||||||
|
stateSinkObject.Save(2, &i.Flags)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (i *IOUringCqe) afterLoad(context.Context) {}
|
||||||
|
|
||||||
|
// +checklocksignore
|
||||||
|
func (i *IOUringCqe) StateLoad(ctx context.Context, stateSourceObject state.Source) {
|
||||||
|
stateSourceObject.Load(0, &i.UserData)
|
||||||
|
stateSourceObject.Load(1, &i.Res)
|
||||||
|
stateSourceObject.Load(2, &i.Flags)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (i *IOUring) StateTypeName() string {
|
||||||
|
return "pkg/abi/linux.IOUring"
|
||||||
|
}
|
||||||
|
|
||||||
|
func (i *IOUring) StateFields() []string {
|
||||||
|
return []string{
|
||||||
|
"Head",
|
||||||
|
"Tail",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (i *IOUring) beforeSave() {}
|
||||||
|
|
||||||
|
// +checklocksignore
|
||||||
|
func (i *IOUring) StateSave(stateSinkObject state.Sink) {
|
||||||
|
i.beforeSave()
|
||||||
|
stateSinkObject.Save(0, &i.Head)
|
||||||
|
stateSinkObject.Save(1, &i.Tail)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (i *IOUring) afterLoad(context.Context) {}
|
||||||
|
|
||||||
|
// +checklocksignore
|
||||||
|
func (i *IOUring) StateLoad(ctx context.Context, stateSourceObject state.Source) {
|
||||||
|
stateSourceObject.Load(0, &i.Head)
|
||||||
|
stateSourceObject.Load(1, &i.Tail)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (i *IORings) StateTypeName() string {
|
||||||
|
return "pkg/abi/linux.IORings"
|
||||||
|
}
|
||||||
|
|
||||||
|
func (i *IORings) StateFields() []string {
|
||||||
|
return []string{
|
||||||
|
"Sq",
|
||||||
|
"Cq",
|
||||||
|
"SqRingMask",
|
||||||
|
"CqRingMask",
|
||||||
|
"SqRingEntries",
|
||||||
|
"CqRingEntries",
|
||||||
|
"sqDropped",
|
||||||
|
"sqFlags",
|
||||||
|
"cqFlags",
|
||||||
|
"CqOverflow",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (i *IORings) beforeSave() {}
|
||||||
|
|
||||||
|
// +checklocksignore
|
||||||
|
func (i *IORings) StateSave(stateSinkObject state.Sink) {
|
||||||
|
i.beforeSave()
|
||||||
|
stateSinkObject.Save(0, &i.Sq)
|
||||||
|
stateSinkObject.Save(1, &i.Cq)
|
||||||
|
stateSinkObject.Save(2, &i.SqRingMask)
|
||||||
|
stateSinkObject.Save(3, &i.CqRingMask)
|
||||||
|
stateSinkObject.Save(4, &i.SqRingEntries)
|
||||||
|
stateSinkObject.Save(5, &i.CqRingEntries)
|
||||||
|
stateSinkObject.Save(6, &i.sqDropped)
|
||||||
|
stateSinkObject.Save(7, &i.sqFlags)
|
||||||
|
stateSinkObject.Save(8, &i.cqFlags)
|
||||||
|
stateSinkObject.Save(9, &i.CqOverflow)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (i *IORings) afterLoad(context.Context) {}
|
||||||
|
|
||||||
|
// +checklocksignore
|
||||||
|
func (i *IORings) StateLoad(ctx context.Context, stateSourceObject state.Source) {
|
||||||
|
stateSourceObject.Load(0, &i.Sq)
|
||||||
|
stateSourceObject.Load(1, &i.Cq)
|
||||||
|
stateSourceObject.Load(2, &i.SqRingMask)
|
||||||
|
stateSourceObject.Load(3, &i.CqRingMask)
|
||||||
|
stateSourceObject.Load(4, &i.SqRingEntries)
|
||||||
|
stateSourceObject.Load(5, &i.CqRingEntries)
|
||||||
|
stateSourceObject.Load(6, &i.sqDropped)
|
||||||
|
stateSourceObject.Load(7, &i.sqFlags)
|
||||||
|
stateSourceObject.Load(8, &i.cqFlags)
|
||||||
|
stateSourceObject.Load(9, &i.CqOverflow)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (i *IOUringSqe) StateTypeName() string {
|
||||||
|
return "pkg/abi/linux.IOUringSqe"
|
||||||
|
}
|
||||||
|
|
||||||
|
func (i *IOUringSqe) StateFields() []string {
|
||||||
|
return []string{
|
||||||
|
"Opcode",
|
||||||
|
"Flags",
|
||||||
|
"IoPrio",
|
||||||
|
"Fd",
|
||||||
|
"OffOrAddrOrCmdOp",
|
||||||
|
"AddrOrSpliceOff",
|
||||||
|
"Len",
|
||||||
|
"specialFlags",
|
||||||
|
"UserData",
|
||||||
|
"BufIndexOrGroup",
|
||||||
|
"personality",
|
||||||
|
"spliceFDOrFileIndex",
|
||||||
|
"addr3",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (i *IOUringSqe) beforeSave() {}
|
||||||
|
|
||||||
|
// +checklocksignore
|
||||||
|
func (i *IOUringSqe) StateSave(stateSinkObject state.Sink) {
|
||||||
|
i.beforeSave()
|
||||||
|
stateSinkObject.Save(0, &i.Opcode)
|
||||||
|
stateSinkObject.Save(1, &i.Flags)
|
||||||
|
stateSinkObject.Save(2, &i.IoPrio)
|
||||||
|
stateSinkObject.Save(3, &i.Fd)
|
||||||
|
stateSinkObject.Save(4, &i.OffOrAddrOrCmdOp)
|
||||||
|
stateSinkObject.Save(5, &i.AddrOrSpliceOff)
|
||||||
|
stateSinkObject.Save(6, &i.Len)
|
||||||
|
stateSinkObject.Save(7, &i.specialFlags)
|
||||||
|
stateSinkObject.Save(8, &i.UserData)
|
||||||
|
stateSinkObject.Save(9, &i.BufIndexOrGroup)
|
||||||
|
stateSinkObject.Save(10, &i.personality)
|
||||||
|
stateSinkObject.Save(11, &i.spliceFDOrFileIndex)
|
||||||
|
stateSinkObject.Save(12, &i.addr3)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (i *IOUringSqe) afterLoad(context.Context) {}
|
||||||
|
|
||||||
|
// +checklocksignore
|
||||||
|
func (i *IOUringSqe) StateLoad(ctx context.Context, stateSourceObject state.Source) {
|
||||||
|
stateSourceObject.Load(0, &i.Opcode)
|
||||||
|
stateSourceObject.Load(1, &i.Flags)
|
||||||
|
stateSourceObject.Load(2, &i.IoPrio)
|
||||||
|
stateSourceObject.Load(3, &i.Fd)
|
||||||
|
stateSourceObject.Load(4, &i.OffOrAddrOrCmdOp)
|
||||||
|
stateSourceObject.Load(5, &i.AddrOrSpliceOff)
|
||||||
|
stateSourceObject.Load(6, &i.Len)
|
||||||
|
stateSourceObject.Load(7, &i.specialFlags)
|
||||||
|
stateSourceObject.Load(8, &i.UserData)
|
||||||
|
stateSourceObject.Load(9, &i.BufIndexOrGroup)
|
||||||
|
stateSourceObject.Load(10, &i.personality)
|
||||||
|
stateSourceObject.Load(11, &i.spliceFDOrFileIndex)
|
||||||
|
stateSourceObject.Load(12, &i.addr3)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *SigAction) StateTypeName() string {
|
||||||
|
return "pkg/abi/linux.SigAction"
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *SigAction) StateFields() []string {
|
||||||
|
return []string{
|
||||||
|
"Handler",
|
||||||
|
"Flags",
|
||||||
|
"Restorer",
|
||||||
|
"Mask",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *SigAction) beforeSave() {}
|
||||||
|
|
||||||
|
// +checklocksignore
|
||||||
|
func (s *SigAction) StateSave(stateSinkObject state.Sink) {
|
||||||
|
s.beforeSave()
|
||||||
|
stateSinkObject.Save(0, &s.Handler)
|
||||||
|
stateSinkObject.Save(1, &s.Flags)
|
||||||
|
stateSinkObject.Save(2, &s.Restorer)
|
||||||
|
stateSinkObject.Save(3, &s.Mask)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *SigAction) afterLoad(context.Context) {}
|
||||||
|
|
||||||
|
// +checklocksignore
|
||||||
|
func (s *SigAction) StateLoad(ctx context.Context, stateSourceObject state.Source) {
|
||||||
|
stateSourceObject.Load(0, &s.Handler)
|
||||||
|
stateSourceObject.Load(1, &s.Flags)
|
||||||
|
stateSourceObject.Load(2, &s.Restorer)
|
||||||
|
stateSourceObject.Load(3, &s.Mask)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *SignalStack) StateTypeName() string {
|
||||||
|
return "pkg/abi/linux.SignalStack"
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *SignalStack) StateFields() []string {
|
||||||
|
return []string{
|
||||||
|
"Addr",
|
||||||
|
"Flags",
|
||||||
|
"Size",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *SignalStack) beforeSave() {}
|
||||||
|
|
||||||
|
// +checklocksignore
|
||||||
|
func (s *SignalStack) StateSave(stateSinkObject state.Sink) {
|
||||||
|
s.beforeSave()
|
||||||
|
stateSinkObject.Save(0, &s.Addr)
|
||||||
|
stateSinkObject.Save(1, &s.Flags)
|
||||||
|
stateSinkObject.Save(2, &s.Size)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *SignalStack) afterLoad(context.Context) {}
|
||||||
|
|
||||||
|
// +checklocksignore
|
||||||
|
func (s *SignalStack) StateLoad(ctx context.Context, stateSourceObject state.Source) {
|
||||||
|
stateSourceObject.Load(0, &s.Addr)
|
||||||
|
stateSourceObject.Load(1, &s.Flags)
|
||||||
|
stateSourceObject.Load(2, &s.Size)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *SignalInfo) StateTypeName() string {
|
||||||
|
return "pkg/abi/linux.SignalInfo"
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *SignalInfo) StateFields() []string {
|
||||||
|
return []string{
|
||||||
|
"Signo",
|
||||||
|
"Errno",
|
||||||
|
"Code",
|
||||||
|
"Fields",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *SignalInfo) beforeSave() {}
|
||||||
|
|
||||||
|
// +checklocksignore
|
||||||
|
func (s *SignalInfo) StateSave(stateSinkObject state.Sink) {
|
||||||
|
s.beforeSave()
|
||||||
|
stateSinkObject.Save(0, &s.Signo)
|
||||||
|
stateSinkObject.Save(1, &s.Errno)
|
||||||
|
stateSinkObject.Save(2, &s.Code)
|
||||||
|
stateSinkObject.Save(3, &s.Fields)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *SignalInfo) afterLoad(context.Context) {}
|
||||||
|
|
||||||
|
// +checklocksignore
|
||||||
|
func (s *SignalInfo) StateLoad(ctx context.Context, stateSourceObject state.Source) {
|
||||||
|
stateSourceObject.Load(0, &s.Signo)
|
||||||
|
stateSourceObject.Load(1, &s.Errno)
|
||||||
|
stateSourceObject.Load(2, &s.Code)
|
||||||
|
stateSourceObject.Load(3, &s.Fields)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *ControlMessageIPPacketInfo) StateTypeName() string {
|
||||||
|
return "pkg/abi/linux.ControlMessageIPPacketInfo"
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *ControlMessageIPPacketInfo) StateFields() []string {
|
||||||
|
return []string{
|
||||||
|
"NIC",
|
||||||
|
"LocalAddr",
|
||||||
|
"DestinationAddr",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *ControlMessageIPPacketInfo) beforeSave() {}
|
||||||
|
|
||||||
|
// +checklocksignore
|
||||||
|
func (c *ControlMessageIPPacketInfo) StateSave(stateSinkObject state.Sink) {
|
||||||
|
c.beforeSave()
|
||||||
|
stateSinkObject.Save(0, &c.NIC)
|
||||||
|
stateSinkObject.Save(1, &c.LocalAddr)
|
||||||
|
stateSinkObject.Save(2, &c.DestinationAddr)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *ControlMessageIPPacketInfo) afterLoad(context.Context) {}
|
||||||
|
|
||||||
|
// +checklocksignore
|
||||||
|
func (c *ControlMessageIPPacketInfo) StateLoad(ctx context.Context, stateSourceObject state.Source) {
|
||||||
|
stateSourceObject.Load(0, &c.NIC)
|
||||||
|
stateSourceObject.Load(1, &c.LocalAddr)
|
||||||
|
stateSourceObject.Load(2, &c.DestinationAddr)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *ControlMessageIPv6PacketInfo) StateTypeName() string {
|
||||||
|
return "pkg/abi/linux.ControlMessageIPv6PacketInfo"
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *ControlMessageIPv6PacketInfo) StateFields() []string {
|
||||||
|
return []string{
|
||||||
|
"Addr",
|
||||||
|
"NIC",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *ControlMessageIPv6PacketInfo) beforeSave() {}
|
||||||
|
|
||||||
|
// +checklocksignore
|
||||||
|
func (c *ControlMessageIPv6PacketInfo) StateSave(stateSinkObject state.Sink) {
|
||||||
|
c.beforeSave()
|
||||||
|
stateSinkObject.Save(0, &c.Addr)
|
||||||
|
stateSinkObject.Save(1, &c.NIC)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *ControlMessageIPv6PacketInfo) afterLoad(context.Context) {}
|
||||||
|
|
||||||
|
// +checklocksignore
|
||||||
|
func (c *ControlMessageIPv6PacketInfo) StateLoad(ctx context.Context, stateSourceObject state.Source) {
|
||||||
|
stateSourceObject.Load(0, &c.Addr)
|
||||||
|
stateSourceObject.Load(1, &c.NIC)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (i *ICMP6Filter) StateTypeName() string {
|
||||||
|
return "pkg/abi/linux.ICMP6Filter"
|
||||||
|
}
|
||||||
|
|
||||||
|
func (i *ICMP6Filter) StateFields() []string {
|
||||||
|
return []string{
|
||||||
|
"Filter",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (i *ICMP6Filter) beforeSave() {}
|
||||||
|
|
||||||
|
// +checklocksignore
|
||||||
|
func (i *ICMP6Filter) StateSave(stateSinkObject state.Sink) {
|
||||||
|
i.beforeSave()
|
||||||
|
stateSinkObject.Save(0, &i.Filter)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (i *ICMP6Filter) afterLoad(context.Context) {}
|
||||||
|
|
||||||
|
// +checklocksignore
|
||||||
|
func (i *ICMP6Filter) StateLoad(ctx context.Context, stateSourceObject state.Source) {
|
||||||
|
stateSourceObject.Load(0, &i.Filter)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t *KernelTermios) StateTypeName() string {
|
||||||
|
return "pkg/abi/linux.KernelTermios"
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t *KernelTermios) StateFields() []string {
|
||||||
|
return []string{
|
||||||
|
"InputFlags",
|
||||||
|
"OutputFlags",
|
||||||
|
"ControlFlags",
|
||||||
|
"LocalFlags",
|
||||||
|
"LineDiscipline",
|
||||||
|
"ControlCharacters",
|
||||||
|
"InputSpeed",
|
||||||
|
"OutputSpeed",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t *KernelTermios) beforeSave() {}
|
||||||
|
|
||||||
|
// +checklocksignore
|
||||||
|
func (t *KernelTermios) StateSave(stateSinkObject state.Sink) {
|
||||||
|
t.beforeSave()
|
||||||
|
stateSinkObject.Save(0, &t.InputFlags)
|
||||||
|
stateSinkObject.Save(1, &t.OutputFlags)
|
||||||
|
stateSinkObject.Save(2, &t.ControlFlags)
|
||||||
|
stateSinkObject.Save(3, &t.LocalFlags)
|
||||||
|
stateSinkObject.Save(4, &t.LineDiscipline)
|
||||||
|
stateSinkObject.Save(5, &t.ControlCharacters)
|
||||||
|
stateSinkObject.Save(6, &t.InputSpeed)
|
||||||
|
stateSinkObject.Save(7, &t.OutputSpeed)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t *KernelTermios) afterLoad(context.Context) {}
|
||||||
|
|
||||||
|
// +checklocksignore
|
||||||
|
func (t *KernelTermios) StateLoad(ctx context.Context, stateSourceObject state.Source) {
|
||||||
|
stateSourceObject.Load(0, &t.InputFlags)
|
||||||
|
stateSourceObject.Load(1, &t.OutputFlags)
|
||||||
|
stateSourceObject.Load(2, &t.ControlFlags)
|
||||||
|
stateSourceObject.Load(3, &t.LocalFlags)
|
||||||
|
stateSourceObject.Load(4, &t.LineDiscipline)
|
||||||
|
stateSourceObject.Load(5, &t.ControlCharacters)
|
||||||
|
stateSourceObject.Load(6, &t.InputSpeed)
|
||||||
|
stateSourceObject.Load(7, &t.OutputSpeed)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (w *WindowSize) StateTypeName() string {
|
||||||
|
return "pkg/abi/linux.WindowSize"
|
||||||
|
}
|
||||||
|
|
||||||
|
func (w *WindowSize) StateFields() []string {
|
||||||
|
return []string{
|
||||||
|
"Rows",
|
||||||
|
"Cols",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (w *WindowSize) beforeSave() {}
|
||||||
|
|
||||||
|
// +checklocksignore
|
||||||
|
func (w *WindowSize) StateSave(stateSinkObject state.Sink) {
|
||||||
|
w.beforeSave()
|
||||||
|
stateSinkObject.Save(0, &w.Rows)
|
||||||
|
stateSinkObject.Save(1, &w.Cols)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (w *WindowSize) afterLoad(context.Context) {}
|
||||||
|
|
||||||
|
// +checklocksignore
|
||||||
|
func (w *WindowSize) StateLoad(ctx context.Context, stateSourceObject state.Source) {
|
||||||
|
stateSourceObject.Load(0, &w.Rows)
|
||||||
|
stateSourceObject.Load(1, &w.Cols)
|
||||||
|
}
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
state.Register((*IOEvent)(nil))
|
||||||
|
state.Register((*BPFInstruction)(nil))
|
||||||
|
state.Register((*FUSEHeaderIn)(nil))
|
||||||
|
state.Register((*FUSEHeaderOut)(nil))
|
||||||
|
state.Register((*IOUringCqe)(nil))
|
||||||
|
state.Register((*IOUring)(nil))
|
||||||
|
state.Register((*IORings)(nil))
|
||||||
|
state.Register((*IOUringSqe)(nil))
|
||||||
|
state.Register((*SigAction)(nil))
|
||||||
|
state.Register((*SignalStack)(nil))
|
||||||
|
state.Register((*SignalInfo)(nil))
|
||||||
|
state.Register((*ControlMessageIPPacketInfo)(nil))
|
||||||
|
state.Register((*ControlMessageIPv6PacketInfo)(nil))
|
||||||
|
state.Register((*ICMP6Filter)(nil))
|
||||||
|
state.Register((*KernelTermios)(nil))
|
||||||
|
state.Register((*WindowSize)(nil))
|
||||||
|
}
|
||||||
3
pkg/abi/linux/linux_unsafe_abi_autogen_unsafe.go
Normal file
3
pkg/abi/linux/linux_unsafe_abi_autogen_unsafe.go
Normal file
|
|
@ -0,0 +1,3 @@
|
||||||
|
// Automatically generated marshal implementation. See tools/go_marshal.
|
||||||
|
|
||||||
|
package linux
|
||||||
3
pkg/abi/linux/linux_unsafe_state_autogen.go
Normal file
3
pkg/abi/linux/linux_unsafe_state_autogen.go
Normal file
|
|
@ -0,0 +1,3 @@
|
||||||
|
// automatically generated by stateify.
|
||||||
|
|
||||||
|
package linux
|
||||||
34
pkg/abi/linux/membarrier.go
Normal file
34
pkg/abi/linux/membarrier.go
Normal file
|
|
@ -0,0 +1,34 @@
|
||||||
|
// Copyright 2020 The gVisor 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 linux
|
||||||
|
|
||||||
|
// membarrier(2) commands, from include/uapi/linux/membarrier.h.
|
||||||
|
const (
|
||||||
|
MEMBARRIER_CMD_QUERY = 0
|
||||||
|
MEMBARRIER_CMD_GLOBAL = (1 << 0)
|
||||||
|
MEMBARRIER_CMD_GLOBAL_EXPEDITED = (1 << 1)
|
||||||
|
MEMBARRIER_CMD_REGISTER_GLOBAL_EXPEDITED = (1 << 2)
|
||||||
|
MEMBARRIER_CMD_PRIVATE_EXPEDITED = (1 << 3)
|
||||||
|
MEMBARRIER_CMD_REGISTER_PRIVATE_EXPEDITED = (1 << 4)
|
||||||
|
MEMBARRIER_CMD_PRIVATE_EXPEDITED_SYNC_CORE = (1 << 5)
|
||||||
|
MEMBARRIER_CMD_REGISTER_PRIVATE_EXPEDITED_SYNC_CORE = (1 << 6)
|
||||||
|
MEMBARRIER_CMD_PRIVATE_EXPEDITED_RSEQ = (1 << 7)
|
||||||
|
MEMBARRIER_CMD_REGISTER_PRIVATE_EXPEDITED_RSEQ = (1 << 8)
|
||||||
|
)
|
||||||
|
|
||||||
|
// membarrier(2) flags, from include/uapi/linux/membarrier.h.
|
||||||
|
const (
|
||||||
|
MEMBARRIER_CMD_FLAG_CPU = (1 << 0)
|
||||||
|
)
|
||||||
160
pkg/abi/linux/mm.go
Normal file
160
pkg/abi/linux/mm.go
Normal file
|
|
@ -0,0 +1,160 @@
|
||||||
|
// Copyright 2018 The gVisor 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 linux
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
"golang.org/x/sys/unix"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Protections for mmap(2).
|
||||||
|
const (
|
||||||
|
PROT_NONE = 0
|
||||||
|
PROT_READ = 1 << 0
|
||||||
|
PROT_WRITE = 1 << 1
|
||||||
|
PROT_EXEC = 1 << 2
|
||||||
|
PROT_SEM = 1 << 3
|
||||||
|
PROT_GROWSDOWN = 1 << 24
|
||||||
|
PROT_GROWSUP = 1 << 25
|
||||||
|
)
|
||||||
|
|
||||||
|
// Flags for mmap(2).
|
||||||
|
const (
|
||||||
|
MAP_SHARED = 1 << 0
|
||||||
|
MAP_PRIVATE = 1 << 1
|
||||||
|
MAP_DROPPABLE = 1 << 3
|
||||||
|
MAP_FIXED = 1 << 4
|
||||||
|
MAP_ANONYMOUS = 1 << 5
|
||||||
|
MAP_32BIT = 1 << 6 // arch/x86/include/uapi/asm/mman.h
|
||||||
|
MAP_GROWSDOWN = 1 << 8
|
||||||
|
MAP_DENYWRITE = 1 << 11
|
||||||
|
MAP_EXECUTABLE = 1 << 12
|
||||||
|
MAP_LOCKED = 1 << 13
|
||||||
|
MAP_NORESERVE = 1 << 14
|
||||||
|
MAP_POPULATE = 1 << 15
|
||||||
|
MAP_NONBLOCK = 1 << 16
|
||||||
|
MAP_STACK = 1 << 17
|
||||||
|
MAP_HUGETLB = 1 << 18
|
||||||
|
)
|
||||||
|
|
||||||
|
// Flags for mremap(2).
|
||||||
|
const (
|
||||||
|
MREMAP_MAYMOVE = 1 << 0
|
||||||
|
MREMAP_FIXED = 1 << 1
|
||||||
|
)
|
||||||
|
|
||||||
|
// Flags for mlock2(2).
|
||||||
|
const (
|
||||||
|
MLOCK_ONFAULT = 0x01
|
||||||
|
)
|
||||||
|
|
||||||
|
// Flags for mlockall(2).
|
||||||
|
const (
|
||||||
|
MCL_CURRENT = 1
|
||||||
|
MCL_FUTURE = 2
|
||||||
|
MCL_ONFAULT = 4
|
||||||
|
)
|
||||||
|
|
||||||
|
// Advice for madvise(2).
|
||||||
|
const (
|
||||||
|
MADV_NORMAL = 0
|
||||||
|
MADV_RANDOM = 1
|
||||||
|
MADV_SEQUENTIAL = 2
|
||||||
|
MADV_WILLNEED = 3
|
||||||
|
MADV_DONTNEED = 4
|
||||||
|
MADV_REMOVE = 9
|
||||||
|
MADV_DONTFORK = 10
|
||||||
|
MADV_DOFORK = 11
|
||||||
|
MADV_MERGEABLE = 12
|
||||||
|
MADV_UNMERGEABLE = 13
|
||||||
|
MADV_HUGEPAGE = 14
|
||||||
|
MADV_NOHUGEPAGE = 15
|
||||||
|
MADV_DONTDUMP = 16
|
||||||
|
MADV_DODUMP = 17
|
||||||
|
MADV_HWPOISON = 100
|
||||||
|
MADV_SOFT_OFFLINE = 101
|
||||||
|
MADV_NOMAJFAULT = 200
|
||||||
|
MADV_DONTCHGME = 201
|
||||||
|
)
|
||||||
|
|
||||||
|
// Flags for msync(2).
|
||||||
|
const (
|
||||||
|
MS_ASYNC = 1 << 0
|
||||||
|
MS_INVALIDATE = 1 << 1
|
||||||
|
MS_SYNC = 1 << 2
|
||||||
|
)
|
||||||
|
|
||||||
|
// NumaPolicy is the NUMA memory policy for a memory range. See numa(7).
|
||||||
|
//
|
||||||
|
// +marshal
|
||||||
|
type NumaPolicy int32
|
||||||
|
|
||||||
|
// Policies for get_mempolicy(2)/set_mempolicy(2).
|
||||||
|
const (
|
||||||
|
MPOL_DEFAULT NumaPolicy = 0
|
||||||
|
MPOL_PREFERRED NumaPolicy = 1
|
||||||
|
MPOL_BIND NumaPolicy = 2
|
||||||
|
MPOL_INTERLEAVE NumaPolicy = 3
|
||||||
|
MPOL_LOCAL NumaPolicy = 4
|
||||||
|
MPOL_MAX NumaPolicy = 5
|
||||||
|
)
|
||||||
|
|
||||||
|
// Flags for get_mempolicy(2).
|
||||||
|
const (
|
||||||
|
MPOL_F_NODE = 1 << 0
|
||||||
|
MPOL_F_ADDR = 1 << 1
|
||||||
|
MPOL_F_MEMS_ALLOWED = 1 << 2
|
||||||
|
)
|
||||||
|
|
||||||
|
// Flags for set_mempolicy(2).
|
||||||
|
const (
|
||||||
|
MPOL_F_RELATIVE_NODES = 1 << 14
|
||||||
|
MPOL_F_STATIC_NODES = 1 << 15
|
||||||
|
|
||||||
|
MPOL_MODE_FLAGS = (MPOL_F_STATIC_NODES | MPOL_F_RELATIVE_NODES)
|
||||||
|
)
|
||||||
|
|
||||||
|
// Flags for mbind(2).
|
||||||
|
const (
|
||||||
|
MPOL_MF_STRICT = 1 << 0
|
||||||
|
MPOL_MF_MOVE = 1 << 1
|
||||||
|
MPOL_MF_MOVE_ALL = 1 << 2
|
||||||
|
|
||||||
|
MPOL_MF_VALID = MPOL_MF_STRICT | MPOL_MF_MOVE | MPOL_MF_MOVE_ALL
|
||||||
|
)
|
||||||
|
|
||||||
|
// TaskSize is the address space size.
|
||||||
|
var TaskSize = func() uintptr {
|
||||||
|
pageSize := uintptr(unix.Getpagesize())
|
||||||
|
for _, s := range feasibleTaskSizes {
|
||||||
|
// mmap returns ENOMEM if addr is greater than TASK_SIZE,
|
||||||
|
// otherwise it returns EINVAL, because addr isn't aligned to
|
||||||
|
// the page size.
|
||||||
|
_, _, errno := unix.RawSyscall6(
|
||||||
|
unix.SYS_MMAP,
|
||||||
|
s-pageSize-1,
|
||||||
|
512,
|
||||||
|
uintptr(unix.PROT_NONE),
|
||||||
|
uintptr(unix.MAP_ANONYMOUS|unix.MAP_PRIVATE|unix.MAP_FIXED), 0, 0)
|
||||||
|
if errno == unix.EINVAL {
|
||||||
|
return s
|
||||||
|
}
|
||||||
|
if errno != unix.ENOMEM {
|
||||||
|
panic(fmt.Sprintf("mmap returned unexpected error: %d", errno))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
panic("None of the address space sizes could be successfully mmaped")
|
||||||
|
}()
|
||||||
33
pkg/abi/linux/mm_amd64.go
Normal file
33
pkg/abi/linux/mm_amd64.go
Normal file
|
|
@ -0,0 +1,33 @@
|
||||||
|
// Copyright 2023 The gVisor 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.
|
||||||
|
|
||||||
|
//go:build amd64
|
||||||
|
// +build amd64
|
||||||
|
|
||||||
|
package linux
|
||||||
|
|
||||||
|
// TASK_SIZE can be one of two values, corresponding to 4-level and 5-level
|
||||||
|
// paging.
|
||||||
|
//
|
||||||
|
// The array has to be sorted in decreasing order.
|
||||||
|
var feasibleTaskSizes = []uintptr{0xfffffffffff000, 0x7ffffffff000}
|
||||||
|
|
||||||
|
// Page fault error codes
|
||||||
|
const (
|
||||||
|
X86_PF_PROT = 1 << iota
|
||||||
|
X86_PF_WRITE
|
||||||
|
X86_PF_USER
|
||||||
|
X86_PF_RSVD
|
||||||
|
X86_PF_INSTR
|
||||||
|
)
|
||||||
25
pkg/abi/linux/mm_arm64.go
Normal file
25
pkg/abi/linux/mm_arm64.go
Normal file
|
|
@ -0,0 +1,25 @@
|
||||||
|
// Copyright 2023 The gVisor 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.
|
||||||
|
|
||||||
|
//go:build arm64
|
||||||
|
// +build arm64
|
||||||
|
|
||||||
|
package linux
|
||||||
|
|
||||||
|
// Only 4K page size is supported on arm64. In this case, TASK_SIZE can
|
||||||
|
// be one of three values, corresponding to 3-level, 4-level and
|
||||||
|
// 5-level paging.
|
||||||
|
//
|
||||||
|
// The array has to be sorted in decreasing order.
|
||||||
|
var feasibleTaskSizes = []uintptr{1 << 52, 1 << 48, 1 << 39}
|
||||||
55
pkg/abi/linux/mqueue.go
Normal file
55
pkg/abi/linux/mqueue.go
Normal file
|
|
@ -0,0 +1,55 @@
|
||||||
|
// Copyright 2021 The gVisor 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 linux
|
||||||
|
|
||||||
|
// Default values for POSIX message queues. Source:
|
||||||
|
// include/linux/ipc_namespace.h
|
||||||
|
const (
|
||||||
|
DFLT_QUEUESMAX = 256
|
||||||
|
MIN_MSGMAX = 1
|
||||||
|
DFLT_MSG uint = 10
|
||||||
|
DFLT_MSGMAX = 10
|
||||||
|
HARD_MSGMAX = 65536
|
||||||
|
MIN_MSGSIZEMAX = 128
|
||||||
|
DFLT_MSGSIZE uint = 8192
|
||||||
|
DFLT_MSGSIZEMAX = 8192
|
||||||
|
HARD_MSGSIZEMAX = (16 * 1024 * 1024)
|
||||||
|
)
|
||||||
|
|
||||||
|
// Maximum values for a message queue. Source: include/uapi/linux/mqueue.h
|
||||||
|
const (
|
||||||
|
MQ_PRIO_MAX = 32768
|
||||||
|
MQ_BYTES_MAX = 819200
|
||||||
|
)
|
||||||
|
|
||||||
|
// Codes used by mq_notify. Source: include/uapi/linux/mqueue.h
|
||||||
|
const (
|
||||||
|
NOTIFY_NONE = 0
|
||||||
|
NOTIFY_WOKENUP = 1
|
||||||
|
NOTIFY_REMOVED = 2
|
||||||
|
|
||||||
|
NOTIFY_COOKIE_LEN = 32
|
||||||
|
)
|
||||||
|
|
||||||
|
// MqAttr is equivalent to struct mq_attr. Source: include/uapi/linux/mqueue.h
|
||||||
|
//
|
||||||
|
// +marshal
|
||||||
|
type MqAttr struct {
|
||||||
|
MqFlags int64 // Message queue flags.
|
||||||
|
MqMaxmsg int64 // Maximum number of messages.
|
||||||
|
MqMsgsize int64 // Maximum message size.
|
||||||
|
MqCurmsgs int64 // Number of messages currently queued.
|
||||||
|
_ [4]int64 // Ignored for input, zeroed for output.
|
||||||
|
}
|
||||||
108
pkg/abi/linux/msgqueue.go
Normal file
108
pkg/abi/linux/msgqueue.go
Normal file
|
|
@ -0,0 +1,108 @@
|
||||||
|
// Copyright 2021 The gVisor 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 linux
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/sagernet/gvisor/pkg/marshal/primitive"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Linux-specific control commands. Source: include/uapi/linux/msg.h
|
||||||
|
const (
|
||||||
|
MSG_STAT = 11
|
||||||
|
MSG_INFO = 12
|
||||||
|
MSG_STAT_ANY = 13
|
||||||
|
)
|
||||||
|
|
||||||
|
// msgrcv(2) options. Source: include/uapi/linux/msg.h
|
||||||
|
const (
|
||||||
|
MSG_NOERROR = 0o10000 // No error if message is too big.
|
||||||
|
MSG_EXCEPT = 0o20000 // Receive any message except of specified type.
|
||||||
|
MSG_COPY = 0o40000 // Copy (not remove) all queue messages.
|
||||||
|
)
|
||||||
|
|
||||||
|
// System-wide limits for message queues. Source: include/uapi/linux/msg.h
|
||||||
|
const (
|
||||||
|
MSGMNI = 32000 // Maximum number of message queue identifiers.
|
||||||
|
MSGMAX = 8192 // Maximum size of message (bytes).
|
||||||
|
MSGMNB = 16384 // Default max size of a message queue.
|
||||||
|
)
|
||||||
|
|
||||||
|
// System-wide limits. Unused. Source: include/uapi/linux/msg.h
|
||||||
|
const (
|
||||||
|
MSGPOOL = (MSGMNI * MSGMNB / 1024)
|
||||||
|
MSGTQL = MSGMNB
|
||||||
|
MSGMAP = MSGMNB
|
||||||
|
MSGSSZ = 16
|
||||||
|
|
||||||
|
// MSGSEG is simplified due to the inexistance of a ternary operator.
|
||||||
|
MSGSEG = 0xffff
|
||||||
|
)
|
||||||
|
|
||||||
|
// MsqidDS is equivalent to struct msqid64_ds. Source:
|
||||||
|
// include/uapi/asm-generic/shmbuf.h
|
||||||
|
//
|
||||||
|
// +marshal
|
||||||
|
type MsqidDS struct {
|
||||||
|
MsgPerm IPCPerm // IPC permissions.
|
||||||
|
MsgStime TimeT // Last msgsnd time.
|
||||||
|
MsgRtime TimeT // Last msgrcv time.
|
||||||
|
MsgCtime TimeT // Last change time.
|
||||||
|
MsgCbytes uint64 // Current number of bytes on the queue.
|
||||||
|
MsgQnum uint64 // Number of messages in the queue.
|
||||||
|
MsgQbytes uint64 // Max number of bytes in the queue.
|
||||||
|
MsgLspid int32 // PID of last msgsnd.
|
||||||
|
MsgLrpid int32 // PID of last msgrcv.
|
||||||
|
unused4 uint64
|
||||||
|
unused5 uint64
|
||||||
|
}
|
||||||
|
|
||||||
|
// MsgBuf is equivalent to struct msgbuf. Source: include/uapi/linux/msg.h
|
||||||
|
//
|
||||||
|
// +marshal dynamic
|
||||||
|
type MsgBuf struct {
|
||||||
|
Type primitive.Int64
|
||||||
|
Text primitive.ByteSlice
|
||||||
|
}
|
||||||
|
|
||||||
|
// SizeBytes implements marshal.Marshallable.SizeBytes.
|
||||||
|
func (b *MsgBuf) SizeBytes() int {
|
||||||
|
return b.Type.SizeBytes() + b.Text.SizeBytes()
|
||||||
|
}
|
||||||
|
|
||||||
|
// MarshalBytes implements marshal.Marshallable.MarshalBytes.
|
||||||
|
func (b *MsgBuf) MarshalBytes(dst []byte) []byte {
|
||||||
|
dst = b.Type.MarshalUnsafe(dst)
|
||||||
|
return b.Text.MarshalBytes(dst)
|
||||||
|
}
|
||||||
|
|
||||||
|
// UnmarshalBytes implements marshal.Marshallable.UnmarshalBytes.
|
||||||
|
func (b *MsgBuf) UnmarshalBytes(src []byte) []byte {
|
||||||
|
src = b.Type.UnmarshalUnsafe(src)
|
||||||
|
return b.Text.UnmarshalBytes(src)
|
||||||
|
}
|
||||||
|
|
||||||
|
// MsgInfo is equivalent to struct msginfo. Source: include/uapi/linux/msg.h
|
||||||
|
//
|
||||||
|
// +marshal
|
||||||
|
type MsgInfo struct {
|
||||||
|
MsgPool int32
|
||||||
|
MsgMap int32
|
||||||
|
MsgMax int32
|
||||||
|
MsgMnb int32
|
||||||
|
MsgMni int32
|
||||||
|
MsgSsz int32
|
||||||
|
MsgTql int32
|
||||||
|
MsgSeg uint16 `marshal:"unaligned"`
|
||||||
|
}
|
||||||
128
pkg/abi/linux/netdevice.go
Normal file
128
pkg/abi/linux/netdevice.go
Normal file
|
|
@ -0,0 +1,128 @@
|
||||||
|
// Copyright 2018 The gVisor 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 linux
|
||||||
|
|
||||||
|
const (
|
||||||
|
// IFNAMSIZ is the size of the name field for IFReq.
|
||||||
|
IFNAMSIZ = 16
|
||||||
|
)
|
||||||
|
|
||||||
|
// IFReq is an interface request.
|
||||||
|
//
|
||||||
|
// +marshal
|
||||||
|
type IFReq struct {
|
||||||
|
// IFName is an encoded name, normally null-terminated. This should be
|
||||||
|
// accessed via the Name and SetName functions.
|
||||||
|
IFName [IFNAMSIZ]byte
|
||||||
|
|
||||||
|
// Data is the union of the following structures:
|
||||||
|
//
|
||||||
|
// struct sockaddr ifr_addr;
|
||||||
|
// struct sockaddr ifr_dstaddr;
|
||||||
|
// struct sockaddr ifr_broadaddr;
|
||||||
|
// struct sockaddr ifr_netmask;
|
||||||
|
// struct sockaddr ifr_hwaddr;
|
||||||
|
// short ifr_flags;
|
||||||
|
// int ifr_ifindex;
|
||||||
|
// int ifr_metric;
|
||||||
|
// int ifr_mtu;
|
||||||
|
// struct ifmap ifr_map;
|
||||||
|
// char ifr_slave[IFNAMSIZ];
|
||||||
|
// char ifr_newname[IFNAMSIZ];
|
||||||
|
// char *ifr_data;
|
||||||
|
Data [24]byte
|
||||||
|
}
|
||||||
|
|
||||||
|
// Name returns the name.
|
||||||
|
func (ifr *IFReq) Name() string {
|
||||||
|
for c := 0; c < len(ifr.IFName); c++ {
|
||||||
|
if ifr.IFName[c] == 0 {
|
||||||
|
return string(ifr.IFName[:c])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return string(ifr.IFName[:])
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetName sets the name.
|
||||||
|
func (ifr *IFReq) SetName(name string) {
|
||||||
|
n := copy(ifr.IFName[:], []byte(name))
|
||||||
|
clear(ifr.IFName[n:])
|
||||||
|
}
|
||||||
|
|
||||||
|
// SizeOfIFReq is the binary size of an IFReq struct (40 bytes).
|
||||||
|
var SizeOfIFReq = (*IFReq)(nil).SizeBytes()
|
||||||
|
|
||||||
|
// IFMap contains interface hardware parameters.
|
||||||
|
type IFMap struct {
|
||||||
|
MemStart uint64
|
||||||
|
MemEnd uint64
|
||||||
|
BaseAddr int16
|
||||||
|
IRQ byte
|
||||||
|
DMA byte
|
||||||
|
Port byte
|
||||||
|
_ [3]byte // Pad to sizeof(struct ifmap).
|
||||||
|
}
|
||||||
|
|
||||||
|
// IFConf is used to return a list of interfaces and their addresses. See
|
||||||
|
// netdevice(7) and struct ifconf for more detail on its use.
|
||||||
|
//
|
||||||
|
// +marshal
|
||||||
|
type IFConf struct {
|
||||||
|
Len int32
|
||||||
|
_ [4]byte // Pad to sizeof(struct ifconf).
|
||||||
|
Ptr uint64
|
||||||
|
}
|
||||||
|
|
||||||
|
// SizeOfIFConf is the binary size of an IFConf struct (16 bytes).
|
||||||
|
var SizeOfIFConf = (*IFConf)(nil).SizeBytes()
|
||||||
|
|
||||||
|
// EthtoolCmd is a marshallable type to be able to easily copyin the
|
||||||
|
// the command for an SIOCETHTOOL ioctl.
|
||||||
|
//
|
||||||
|
// +marshal
|
||||||
|
type EthtoolCmd uint32
|
||||||
|
|
||||||
|
const (
|
||||||
|
// ETHTOOL_GFEATURES is the command to SIOCETHTOOL to query device
|
||||||
|
// features.
|
||||||
|
// See: <linux/ethtool.h>
|
||||||
|
ETHTOOL_GFEATURES EthtoolCmd = 0x3a
|
||||||
|
)
|
||||||
|
|
||||||
|
// EthtoolGFeatures is used to return a list of device features.
|
||||||
|
// See: <linux/ethtool.h>
|
||||||
|
//
|
||||||
|
// +marshal
|
||||||
|
type EthtoolGFeatures struct {
|
||||||
|
Cmd uint32
|
||||||
|
Size uint32
|
||||||
|
}
|
||||||
|
|
||||||
|
// EthtoolGetFeaturesBlock is used to return state of upto 32 device
|
||||||
|
// features.
|
||||||
|
// See: <linux/ethtool.h>
|
||||||
|
//
|
||||||
|
// +marshal
|
||||||
|
type EthtoolGetFeaturesBlock struct {
|
||||||
|
Available uint32
|
||||||
|
Requested uint32
|
||||||
|
Active uint32
|
||||||
|
NeverChanged uint32
|
||||||
|
}
|
||||||
|
|
||||||
|
const (
|
||||||
|
// LOOPBACK_IFINDEX is defined in include/net/flow.h.
|
||||||
|
LOOPBACK_IFINDEX = 1
|
||||||
|
)
|
||||||
796
pkg/abi/linux/netfilter.go
Normal file
796
pkg/abi/linux/netfilter.go
Normal file
|
|
@ -0,0 +1,796 @@
|
||||||
|
// Copyright 2019 The gVisor 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 linux
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/sagernet/gvisor/pkg/marshal"
|
||||||
|
"github.com/sagernet/gvisor/pkg/marshal/primitive"
|
||||||
|
)
|
||||||
|
|
||||||
|
// This file contains structures required to support netfilter, specifically
|
||||||
|
// the iptables tool.
|
||||||
|
|
||||||
|
// Hooks into the network stack. These correspond to values in
|
||||||
|
// include/uapi/linux/netfilter.h.
|
||||||
|
const (
|
||||||
|
NF_INET_PRE_ROUTING = 0
|
||||||
|
NF_INET_LOCAL_IN = 1
|
||||||
|
NF_INET_FORWARD = 2
|
||||||
|
NF_INET_LOCAL_OUT = 3
|
||||||
|
NF_INET_POST_ROUTING = 4
|
||||||
|
NF_INET_NUMHOOKS = 5
|
||||||
|
NF_INET_INGRESS = NF_INET_NUMHOOKS
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
NF_NETDEV_INGRESS = iota
|
||||||
|
NF_NETDEV_EGRESS
|
||||||
|
NF_NETDEV_NUMHOOKS
|
||||||
|
)
|
||||||
|
|
||||||
|
// Protocol families (address families). These correspond to values in
|
||||||
|
// include/uapi/linux/netfilter.h.
|
||||||
|
const (
|
||||||
|
NFPROTO_UNSPEC = 0
|
||||||
|
NFPROTO_INET = 1
|
||||||
|
NFPROTO_IPV4 = 2
|
||||||
|
NFPROTO_ARP = 3
|
||||||
|
NFPROTO_NETDEV = 5
|
||||||
|
NFPROTO_BRIDGE = 7
|
||||||
|
NFPROTO_IPV6 = 10
|
||||||
|
)
|
||||||
|
|
||||||
|
// Verdicts that can be returned by targets. These correspond to values in
|
||||||
|
// include/uapi/linux/netfilter.h
|
||||||
|
const (
|
||||||
|
NF_DROP = 0
|
||||||
|
NF_ACCEPT = 1
|
||||||
|
NF_STOLEN = 2
|
||||||
|
NF_QUEUE = 3
|
||||||
|
NF_REPEAT = 4
|
||||||
|
NF_STOP = 5
|
||||||
|
NF_MAX_VERDICT = NF_STOP
|
||||||
|
// NF_RETURN is defined in include/uapi/linux/netfilter/x_tables.h.
|
||||||
|
NF_RETURN = -NF_REPEAT - 1
|
||||||
|
)
|
||||||
|
|
||||||
|
// VerdictStrings maps int verdicts to the strings they represent. It is used
|
||||||
|
// for debugging.
|
||||||
|
var VerdictStrings = map[int32]string{
|
||||||
|
-NF_DROP - 1: "DROP",
|
||||||
|
-NF_ACCEPT - 1: "ACCEPT",
|
||||||
|
-NF_QUEUE - 1: "QUEUE",
|
||||||
|
NF_RETURN: "RETURN",
|
||||||
|
}
|
||||||
|
|
||||||
|
// Socket options for SOL_SOCKET. These correspond to values in
|
||||||
|
// include/uapi/linux/netfilter_ipv4/ip_tables.h.
|
||||||
|
const (
|
||||||
|
IPT_BASE_CTL = 64
|
||||||
|
IPT_SO_SET_REPLACE = IPT_BASE_CTL
|
||||||
|
IPT_SO_SET_ADD_COUNTERS = IPT_BASE_CTL + 1
|
||||||
|
IPT_SO_SET_MAX = IPT_SO_SET_ADD_COUNTERS
|
||||||
|
|
||||||
|
IPT_SO_GET_INFO = IPT_BASE_CTL
|
||||||
|
IPT_SO_GET_ENTRIES = IPT_BASE_CTL + 1
|
||||||
|
IPT_SO_GET_REVISION_MATCH = IPT_BASE_CTL + 2
|
||||||
|
IPT_SO_GET_REVISION_TARGET = IPT_BASE_CTL + 3
|
||||||
|
IPT_SO_GET_MAX = IPT_SO_GET_REVISION_TARGET
|
||||||
|
)
|
||||||
|
|
||||||
|
// Socket option for SOL_IP. This corresponds to the value in
|
||||||
|
// include/uapi/linux/netfilter_ipv4.h.
|
||||||
|
const (
|
||||||
|
SO_ORIGINAL_DST = 80
|
||||||
|
)
|
||||||
|
|
||||||
|
// Name lengths. These correspond to values in
|
||||||
|
// include/uapi/linux/netfilter/x_tables.h.
|
||||||
|
const (
|
||||||
|
XT_FUNCTION_MAXNAMELEN = 30
|
||||||
|
XT_EXTENSION_MAXNAMELEN = 29
|
||||||
|
XT_TABLE_MAXNAMELEN = 32
|
||||||
|
)
|
||||||
|
|
||||||
|
// IPTEntry is an iptable rule. It corresponds to struct ipt_entry in
|
||||||
|
// include/uapi/linux/netfilter_ipv4/ip_tables.h.
|
||||||
|
//
|
||||||
|
// +marshal
|
||||||
|
type IPTEntry struct {
|
||||||
|
// IP is used to filter packets based on the IP header.
|
||||||
|
IP IPTIP
|
||||||
|
|
||||||
|
// NFCache relates to kernel-internal caching and isn't used by
|
||||||
|
// userspace.
|
||||||
|
NFCache uint32
|
||||||
|
|
||||||
|
// TargetOffset is the byte offset from the beginning of this IPTEntry
|
||||||
|
// to the start of the entry's target.
|
||||||
|
TargetOffset uint16
|
||||||
|
|
||||||
|
// NextOffset is the byte offset from the beginning of this IPTEntry to
|
||||||
|
// the start of the next entry. It is thus also the size of the entry.
|
||||||
|
NextOffset uint16
|
||||||
|
|
||||||
|
// Comeback is a return pointer. It is not used by userspace.
|
||||||
|
Comeback uint32
|
||||||
|
|
||||||
|
// Counters holds the packet and byte counts for this rule.
|
||||||
|
Counters XTCounters
|
||||||
|
|
||||||
|
// Elems holds the data for all this rule's matches followed by the
|
||||||
|
// target. It is variable length -- users have to iterate over any
|
||||||
|
// matches and use TargetOffset and NextOffset to make sense of the
|
||||||
|
// data.
|
||||||
|
//
|
||||||
|
// Elems is omitted here because it would cause IPTEntry to be an extra
|
||||||
|
// byte larger (see http://www.catb.org/esr/structure-packing/).
|
||||||
|
//
|
||||||
|
// Elems [0]byte
|
||||||
|
}
|
||||||
|
|
||||||
|
// SizeOfIPTEntry is the size of an IPTEntry.
|
||||||
|
const SizeOfIPTEntry = 112
|
||||||
|
|
||||||
|
// KernelIPTEntry is identical to IPTEntry, but includes the Elems field.
|
||||||
|
//
|
||||||
|
// +marshal dynamic
|
||||||
|
type KernelIPTEntry struct {
|
||||||
|
Entry IPTEntry
|
||||||
|
|
||||||
|
// Elems holds the data for all this rule's matches followed by the
|
||||||
|
// target. It is variable length -- users have to iterate over any
|
||||||
|
// matches and use TargetOffset and NextOffset to make sense of the
|
||||||
|
// data.
|
||||||
|
Elems primitive.ByteSlice
|
||||||
|
}
|
||||||
|
|
||||||
|
// SizeBytes implements marshal.Marshallable.SizeBytes.
|
||||||
|
func (ke *KernelIPTEntry) SizeBytes() int {
|
||||||
|
return ke.Entry.SizeBytes() + ke.Elems.SizeBytes()
|
||||||
|
}
|
||||||
|
|
||||||
|
// MarshalBytes implements marshal.Marshallable.MarshalBytes.
|
||||||
|
func (ke *KernelIPTEntry) MarshalBytes(dst []byte) []byte {
|
||||||
|
dst = ke.Entry.MarshalUnsafe(dst)
|
||||||
|
return ke.Elems.MarshalBytes(dst)
|
||||||
|
}
|
||||||
|
|
||||||
|
// UnmarshalBytes implements marshal.Marshallable.UnmarshalBytes.
|
||||||
|
func (ke *KernelIPTEntry) UnmarshalBytes(src []byte) []byte {
|
||||||
|
src = ke.Entry.UnmarshalUnsafe(src)
|
||||||
|
return ke.Elems.UnmarshalBytes(src)
|
||||||
|
}
|
||||||
|
|
||||||
|
var _ marshal.Marshallable = (*KernelIPTEntry)(nil)
|
||||||
|
|
||||||
|
// IPTIP contains information for matching a packet's IP header.
|
||||||
|
// It corresponds to struct ipt_ip in
|
||||||
|
// include/uapi/linux/netfilter_ipv4/ip_tables.h.
|
||||||
|
//
|
||||||
|
// +marshal
|
||||||
|
type IPTIP struct {
|
||||||
|
// Src is the source IP address.
|
||||||
|
Src InetAddr
|
||||||
|
|
||||||
|
// Dst is the destination IP address.
|
||||||
|
Dst InetAddr
|
||||||
|
|
||||||
|
// SrcMask is the source IP mask.
|
||||||
|
SrcMask InetAddr
|
||||||
|
|
||||||
|
// DstMask is the destination IP mask.
|
||||||
|
DstMask InetAddr
|
||||||
|
|
||||||
|
// InputInterface is the input network interface.
|
||||||
|
InputInterface [IFNAMSIZ]byte
|
||||||
|
|
||||||
|
// OutputInterface is the output network interface.
|
||||||
|
OutputInterface [IFNAMSIZ]byte
|
||||||
|
|
||||||
|
// InputInterfaceMask is the input interface mask.
|
||||||
|
InputInterfaceMask [IFNAMSIZ]byte
|
||||||
|
|
||||||
|
// OuputInterfaceMask is the output interface mask.
|
||||||
|
OutputInterfaceMask [IFNAMSIZ]byte
|
||||||
|
|
||||||
|
// Protocol is the transport protocol.
|
||||||
|
Protocol uint16
|
||||||
|
|
||||||
|
// Flags define matching behavior for the IP header.
|
||||||
|
Flags uint8
|
||||||
|
|
||||||
|
// InverseFlags invert the meaning of fields in struct IPTIP. See the
|
||||||
|
// IPT_INV_* flags.
|
||||||
|
InverseFlags uint8
|
||||||
|
}
|
||||||
|
|
||||||
|
// Flags in IPTIP.InverseFlags. Corresponding constants are in
|
||||||
|
// include/uapi/linux/netfilter_ipv4/ip_tables.h.
|
||||||
|
const (
|
||||||
|
// Invert the meaning of InputInterface.
|
||||||
|
IPT_INV_VIA_IN = 0x01
|
||||||
|
// Invert the meaning of OutputInterface.
|
||||||
|
IPT_INV_VIA_OUT = 0x02
|
||||||
|
// Unclear what this is, as no references to it exist in the kernel.
|
||||||
|
IPT_INV_TOS = 0x04
|
||||||
|
// Invert the meaning of Src.
|
||||||
|
IPT_INV_SRCIP = 0x08
|
||||||
|
// Invert the meaning of Dst.
|
||||||
|
IPT_INV_DSTIP = 0x10
|
||||||
|
// Invert the meaning of the IPT_F_FRAG flag.
|
||||||
|
IPT_INV_FRAG = 0x20
|
||||||
|
// Invert the meaning of the Protocol field.
|
||||||
|
IPT_INV_PROTO = 0x40
|
||||||
|
// Enable all flags.
|
||||||
|
IPT_INV_MASK = 0x7F
|
||||||
|
)
|
||||||
|
|
||||||
|
// SizeOfIPTIP is the size of an IPTIP.
|
||||||
|
const SizeOfIPTIP = 84
|
||||||
|
|
||||||
|
// XTCounters holds packet and byte counts for a rule. It corresponds to struct
|
||||||
|
// xt_counters in include/uapi/linux/netfilter/x_tables.h.
|
||||||
|
//
|
||||||
|
// +marshal
|
||||||
|
type XTCounters struct {
|
||||||
|
// Pcnt is the packet count.
|
||||||
|
Pcnt uint64
|
||||||
|
|
||||||
|
// Bcnt is the byte count.
|
||||||
|
Bcnt uint64
|
||||||
|
}
|
||||||
|
|
||||||
|
// SizeOfXTCounters is the size of an XTCounters.
|
||||||
|
const SizeOfXTCounters = 16
|
||||||
|
|
||||||
|
// XTEntryMatch holds a match for a rule. For example, a user using the
|
||||||
|
// addrtype iptables match extension would put the data for that match into an
|
||||||
|
// XTEntryMatch. iptables-extensions(8) has a list of possible matches.
|
||||||
|
//
|
||||||
|
// XTEntryMatch corresponds to struct xt_entry_match in
|
||||||
|
// include/uapi/linux/netfilter/x_tables.h. That struct contains a union
|
||||||
|
// exposing different data to the user and kernel, but this struct holds only
|
||||||
|
// the user data.
|
||||||
|
//
|
||||||
|
// +marshal
|
||||||
|
type XTEntryMatch struct {
|
||||||
|
MatchSize uint16
|
||||||
|
Name ExtensionName
|
||||||
|
Revision uint8
|
||||||
|
// Data is omitted here because it would cause XTEntryMatch to be an
|
||||||
|
// extra byte larger (see http://www.catb.org/esr/structure-packing/).
|
||||||
|
// Data [0]byte
|
||||||
|
}
|
||||||
|
|
||||||
|
// SizeOfXTEntryMatch is the size of an XTEntryMatch.
|
||||||
|
const SizeOfXTEntryMatch = 32
|
||||||
|
|
||||||
|
// KernelXTEntryMatch is identical to XTEntryMatch, but contains
|
||||||
|
// variable-length Data field.
|
||||||
|
type KernelXTEntryMatch struct {
|
||||||
|
XTEntryMatch
|
||||||
|
Data []byte
|
||||||
|
}
|
||||||
|
|
||||||
|
// XTGetRevision corresponds to xt_get_revision in
|
||||||
|
// include/uapi/linux/netfilter/x_tables.h
|
||||||
|
//
|
||||||
|
// +marshal
|
||||||
|
type XTGetRevision struct {
|
||||||
|
Name ExtensionName
|
||||||
|
Revision uint8
|
||||||
|
}
|
||||||
|
|
||||||
|
// SizeOfXTGetRevision is the size of an XTGetRevision.
|
||||||
|
const SizeOfXTGetRevision = 30
|
||||||
|
|
||||||
|
// XTEntryTarget holds a target for a rule. For example, it can specify that
|
||||||
|
// packets matching the rule should DROP, ACCEPT, or use an extension target.
|
||||||
|
// iptables-extension(8) has a list of possible targets.
|
||||||
|
//
|
||||||
|
// XTEntryTarget corresponds to struct xt_entry_target in
|
||||||
|
// include/uapi/linux/netfilter/x_tables.h. That struct contains a union
|
||||||
|
// exposing different data to the user and kernel, but this struct holds only
|
||||||
|
// the user data.
|
||||||
|
//
|
||||||
|
// +marshal
|
||||||
|
type XTEntryTarget struct {
|
||||||
|
TargetSize uint16
|
||||||
|
Name ExtensionName
|
||||||
|
Revision uint8
|
||||||
|
// Data is omitted here because it would cause XTEntryTarget to be an
|
||||||
|
// extra byte larger (see http://www.catb.org/esr/structure-packing/).
|
||||||
|
// Data [0]byte
|
||||||
|
}
|
||||||
|
|
||||||
|
// SizeOfXTEntryTarget is the size of an XTEntryTarget.
|
||||||
|
const SizeOfXTEntryTarget = 32
|
||||||
|
|
||||||
|
// KernelXTEntryTarget is identical to XTEntryTarget, but contains a
|
||||||
|
// variable-length Data field.
|
||||||
|
type KernelXTEntryTarget struct {
|
||||||
|
XTEntryTarget
|
||||||
|
Data []byte
|
||||||
|
}
|
||||||
|
|
||||||
|
// XTStandardTarget is a built-in target, one of ACCEPT, DROP, JUMP, QUEUE,
|
||||||
|
// RETURN, or jump. It corresponds to struct xt_standard_target in
|
||||||
|
// include/uapi/linux/netfilter/x_tables.h.
|
||||||
|
//
|
||||||
|
// +marshal
|
||||||
|
type XTStandardTarget struct {
|
||||||
|
Target XTEntryTarget
|
||||||
|
// A positive verdict indicates a jump, and is the offset from the
|
||||||
|
// start of the table to jump to. A negative value means one of the
|
||||||
|
// other built-in targets.
|
||||||
|
Verdict int32
|
||||||
|
_ [4]byte
|
||||||
|
}
|
||||||
|
|
||||||
|
// SizeOfXTStandardTarget is the size of an XTStandardTarget.
|
||||||
|
const SizeOfXTStandardTarget = 40
|
||||||
|
|
||||||
|
// XTErrorTarget triggers an error when reached. It is also used to mark the
|
||||||
|
// beginning of user-defined chains by putting the name of the chain in
|
||||||
|
// ErrorName. It corresponds to struct xt_error_target in
|
||||||
|
// include/uapi/linux/netfilter/x_tables.h.
|
||||||
|
//
|
||||||
|
// +marshal
|
||||||
|
type XTErrorTarget struct {
|
||||||
|
Target XTEntryTarget
|
||||||
|
Name ErrorName
|
||||||
|
_ [2]byte
|
||||||
|
}
|
||||||
|
|
||||||
|
// SizeOfXTErrorTarget is the size of an XTErrorTarget.
|
||||||
|
const SizeOfXTErrorTarget = 64
|
||||||
|
|
||||||
|
// Flag values for NfNATIPV4Range. The values indicate whether to map
|
||||||
|
// protocol specific part(ports) or IPs. It corresponds to values in
|
||||||
|
// include/uapi/linux/netfilter/nf_nat.h.
|
||||||
|
const (
|
||||||
|
NF_NAT_RANGE_MAP_IPS = 1 << 0
|
||||||
|
NF_NAT_RANGE_PROTO_SPECIFIED = 1 << 1
|
||||||
|
NF_NAT_RANGE_PROTO_RANDOM = 1 << 2
|
||||||
|
NF_NAT_RANGE_PERSISTENT = 1 << 3
|
||||||
|
NF_NAT_RANGE_PROTO_RANDOM_FULLY = 1 << 4
|
||||||
|
NF_NAT_RANGE_PROTO_RANDOM_ALL = (NF_NAT_RANGE_PROTO_RANDOM | NF_NAT_RANGE_PROTO_RANDOM_FULLY)
|
||||||
|
NF_NAT_RANGE_MASK = (NF_NAT_RANGE_MAP_IPS |
|
||||||
|
NF_NAT_RANGE_PROTO_SPECIFIED | NF_NAT_RANGE_PROTO_RANDOM |
|
||||||
|
NF_NAT_RANGE_PERSISTENT | NF_NAT_RANGE_PROTO_RANDOM_FULLY)
|
||||||
|
)
|
||||||
|
|
||||||
|
// NfNATIPV4Range corresponds to struct nf_nat_ipv4_range
|
||||||
|
// in include/uapi/linux/netfilter/nf_nat.h. The fields are in
|
||||||
|
// network byte order.
|
||||||
|
//
|
||||||
|
// +marshal
|
||||||
|
type NfNATIPV4Range struct {
|
||||||
|
Flags uint32
|
||||||
|
MinIP [4]byte
|
||||||
|
MaxIP [4]byte
|
||||||
|
MinPort uint16
|
||||||
|
MaxPort uint16
|
||||||
|
}
|
||||||
|
|
||||||
|
// NfNATIPV4MultiRangeCompat corresponds to struct
|
||||||
|
// nf_nat_ipv4_multi_range_compat in include/uapi/linux/netfilter/nf_nat.h.
|
||||||
|
//
|
||||||
|
// +marshal
|
||||||
|
type NfNATIPV4MultiRangeCompat struct {
|
||||||
|
RangeSize uint32
|
||||||
|
RangeIPV4 NfNATIPV4Range
|
||||||
|
}
|
||||||
|
|
||||||
|
// XTRedirectTarget triggers a redirect when reached.
|
||||||
|
// Adding 4 bytes of padding to make the struct 8 byte aligned.
|
||||||
|
//
|
||||||
|
// +marshal
|
||||||
|
type XTRedirectTarget struct {
|
||||||
|
Target XTEntryTarget
|
||||||
|
NfRange NfNATIPV4MultiRangeCompat
|
||||||
|
_ [4]byte
|
||||||
|
}
|
||||||
|
|
||||||
|
// SizeOfXTRedirectTarget is the size of an XTRedirectTarget.
|
||||||
|
const SizeOfXTRedirectTarget = 56
|
||||||
|
|
||||||
|
// XTNATTargetV0 triggers NAT when reached.
|
||||||
|
// Adding 4 bytes of padding to make the struct 8 byte aligned.
|
||||||
|
//
|
||||||
|
// +marshal
|
||||||
|
type XTNATTargetV0 struct {
|
||||||
|
Target XTEntryTarget
|
||||||
|
NfRange NfNATIPV4MultiRangeCompat
|
||||||
|
_ [4]byte
|
||||||
|
}
|
||||||
|
|
||||||
|
// SizeOfXTNATTargetV0 is the size of an XTNATTargetV0.
|
||||||
|
const SizeOfXTNATTargetV0 = 56
|
||||||
|
|
||||||
|
// XTNATTargetV1 triggers NAT when reached.
|
||||||
|
//
|
||||||
|
// +marshal
|
||||||
|
type XTNATTargetV1 struct {
|
||||||
|
Target XTEntryTarget
|
||||||
|
Range NFNATRange
|
||||||
|
}
|
||||||
|
|
||||||
|
// SizeOfXTNATTargetV1 is the size of an XTNATTargetV1.
|
||||||
|
const SizeOfXTNATTargetV1 = SizeOfXTEntryTarget + SizeOfNFNATRange
|
||||||
|
|
||||||
|
// XTNATTargetV2 triggers NAT when reached.
|
||||||
|
//
|
||||||
|
// +marshal
|
||||||
|
type XTNATTargetV2 struct {
|
||||||
|
Target XTEntryTarget
|
||||||
|
Range NFNATRange2
|
||||||
|
}
|
||||||
|
|
||||||
|
// SizeOfXTNATTargetV2 is the size of an XTNATTargetV2.
|
||||||
|
const SizeOfXTNATTargetV2 = SizeOfXTEntryTarget + SizeOfNFNATRange2
|
||||||
|
|
||||||
|
// IPTGetinfo is the argument for the IPT_SO_GET_INFO sockopt. It corresponds
|
||||||
|
// to struct ipt_getinfo in include/uapi/linux/netfilter_ipv4/ip_tables.h.
|
||||||
|
//
|
||||||
|
// +marshal
|
||||||
|
type IPTGetinfo struct {
|
||||||
|
Name TableName
|
||||||
|
ValidHooks uint32
|
||||||
|
HookEntry [NF_INET_NUMHOOKS]uint32
|
||||||
|
Underflow [NF_INET_NUMHOOKS]uint32
|
||||||
|
NumEntries uint32
|
||||||
|
Size uint32
|
||||||
|
}
|
||||||
|
|
||||||
|
// SizeOfIPTGetinfo is the size of an IPTGetinfo.
|
||||||
|
const SizeOfIPTGetinfo = 84
|
||||||
|
|
||||||
|
// IPTGetEntries is the argument for the IPT_SO_GET_ENTRIES sockopt. It
|
||||||
|
// corresponds to struct ipt_get_entries in
|
||||||
|
// include/uapi/linux/netfilter_ipv4/ip_tables.h.
|
||||||
|
//
|
||||||
|
// +marshal
|
||||||
|
type IPTGetEntries struct {
|
||||||
|
Name TableName
|
||||||
|
Size uint32
|
||||||
|
_ [4]byte
|
||||||
|
// Entrytable is omitted here because it would cause IPTGetEntries to
|
||||||
|
// be an extra byte longer (see
|
||||||
|
// http://www.catb.org/esr/structure-packing/).
|
||||||
|
// Entrytable [0]IPTEntry
|
||||||
|
}
|
||||||
|
|
||||||
|
// SizeOfIPTGetEntries is the size of an IPTGetEntries.
|
||||||
|
const SizeOfIPTGetEntries = 40
|
||||||
|
|
||||||
|
// KernelIPTGetEntries is identical to IPTGetEntries, but includes the
|
||||||
|
// Entrytable field.
|
||||||
|
//
|
||||||
|
// +marshal dynamic
|
||||||
|
type KernelIPTGetEntries struct {
|
||||||
|
IPTGetEntries
|
||||||
|
Entrytable []KernelIPTEntry
|
||||||
|
}
|
||||||
|
|
||||||
|
// SizeBytes implements marshal.Marshallable.SizeBytes.
|
||||||
|
func (ke *KernelIPTGetEntries) SizeBytes() int {
|
||||||
|
res := ke.IPTGetEntries.SizeBytes()
|
||||||
|
for _, entry := range ke.Entrytable {
|
||||||
|
res += entry.SizeBytes()
|
||||||
|
}
|
||||||
|
return res
|
||||||
|
}
|
||||||
|
|
||||||
|
// MarshalBytes implements marshal.Marshallable.MarshalBytes.
|
||||||
|
func (ke *KernelIPTGetEntries) MarshalBytes(dst []byte) []byte {
|
||||||
|
dst = ke.IPTGetEntries.MarshalUnsafe(dst)
|
||||||
|
for i := range ke.Entrytable {
|
||||||
|
dst = ke.Entrytable[i].MarshalBytes(dst)
|
||||||
|
}
|
||||||
|
return dst
|
||||||
|
}
|
||||||
|
|
||||||
|
// UnmarshalBytes implements marshal.Marshallable.UnmarshalBytes.
|
||||||
|
func (ke *KernelIPTGetEntries) UnmarshalBytes(src []byte) []byte {
|
||||||
|
src = ke.IPTGetEntries.UnmarshalUnsafe(src)
|
||||||
|
for i := range ke.Entrytable {
|
||||||
|
src = ke.Entrytable[i].UnmarshalBytes(src)
|
||||||
|
}
|
||||||
|
return src
|
||||||
|
}
|
||||||
|
|
||||||
|
var _ marshal.Marshallable = (*KernelIPTGetEntries)(nil)
|
||||||
|
|
||||||
|
// IPTReplace is the argument for the IPT_SO_SET_REPLACE sockopt. It
|
||||||
|
// corresponds to struct ipt_replace in
|
||||||
|
// include/uapi/linux/netfilter_ipv4/ip_tables.h.
|
||||||
|
//
|
||||||
|
// +marshal
|
||||||
|
type IPTReplace struct {
|
||||||
|
Name TableName
|
||||||
|
ValidHooks uint32
|
||||||
|
NumEntries uint32
|
||||||
|
Size uint32
|
||||||
|
HookEntry [NF_INET_NUMHOOKS]uint32
|
||||||
|
Underflow [NF_INET_NUMHOOKS]uint32
|
||||||
|
NumCounters uint32
|
||||||
|
Counters uint64 // This is really a *XTCounters.
|
||||||
|
// Entries is omitted here because it would cause IPTReplace to be an
|
||||||
|
// extra byte longer (see http://www.catb.org/esr/structure-packing/).
|
||||||
|
// Entries [0]IPTEntry
|
||||||
|
}
|
||||||
|
|
||||||
|
// SizeOfIPTReplace is the size of an IPTReplace.
|
||||||
|
const SizeOfIPTReplace = 96
|
||||||
|
|
||||||
|
// ExtensionName holds the name of a netfilter extension.
|
||||||
|
//
|
||||||
|
// +marshal
|
||||||
|
type ExtensionName [XT_EXTENSION_MAXNAMELEN]byte
|
||||||
|
|
||||||
|
// String implements fmt.Stringer.
|
||||||
|
func (en ExtensionName) String() string {
|
||||||
|
return goString(en[:])
|
||||||
|
}
|
||||||
|
|
||||||
|
// TableName holds the name of a netfilter table.
|
||||||
|
//
|
||||||
|
// +marshal
|
||||||
|
type TableName [XT_TABLE_MAXNAMELEN]byte
|
||||||
|
|
||||||
|
// String implements fmt.Stringer.
|
||||||
|
func (tn TableName) String() string {
|
||||||
|
return goString(tn[:])
|
||||||
|
}
|
||||||
|
|
||||||
|
// ErrorName holds the name of a netfilter error. These can also hold
|
||||||
|
// user-defined chains.
|
||||||
|
//
|
||||||
|
// +marshal
|
||||||
|
type ErrorName [XT_FUNCTION_MAXNAMELEN]byte
|
||||||
|
|
||||||
|
// String implements fmt.Stringer.
|
||||||
|
func (en ErrorName) String() string {
|
||||||
|
return goString(en[:])
|
||||||
|
}
|
||||||
|
|
||||||
|
func goString(cstring []byte) string {
|
||||||
|
for i, c := range cstring {
|
||||||
|
if c == 0 {
|
||||||
|
return string(cstring[:i])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return string(cstring)
|
||||||
|
}
|
||||||
|
|
||||||
|
// XTTCP holds data for matching TCP packets. It corresponds to struct xt_tcp
|
||||||
|
// in include/uapi/linux/netfilter/xt_tcpudp.h.
|
||||||
|
//
|
||||||
|
// +marshal
|
||||||
|
type XTTCP struct {
|
||||||
|
// SourcePortStart specifies the inclusive start of the range of source
|
||||||
|
// ports to which the matcher applies.
|
||||||
|
SourcePortStart uint16
|
||||||
|
|
||||||
|
// SourcePortEnd specifies the inclusive end of the range of source ports
|
||||||
|
// to which the matcher applies.
|
||||||
|
SourcePortEnd uint16
|
||||||
|
|
||||||
|
// DestinationPortStart specifies the start of the destination port
|
||||||
|
// range to which the matcher applies.
|
||||||
|
DestinationPortStart uint16
|
||||||
|
|
||||||
|
// DestinationPortEnd specifies the end of the destination port
|
||||||
|
// range to which the matcher applies.
|
||||||
|
DestinationPortEnd uint16
|
||||||
|
|
||||||
|
// Option specifies that a particular TCP option must be set.
|
||||||
|
Option uint8
|
||||||
|
|
||||||
|
// FlagMask masks TCP flags when comparing to the FlagCompare byte. It allows
|
||||||
|
// for specification of which flags are important to the matcher.
|
||||||
|
FlagMask uint8
|
||||||
|
|
||||||
|
// FlagCompare, in combination with FlagMask, is used to match only packets
|
||||||
|
// that have certain flags set.
|
||||||
|
FlagCompare uint8
|
||||||
|
|
||||||
|
// InverseFlags flips the meaning of certain fields. See the
|
||||||
|
// TX_TCP_INV_* flags.
|
||||||
|
InverseFlags uint8
|
||||||
|
}
|
||||||
|
|
||||||
|
// SizeOfXTTCP is the size of an XTTCP.
|
||||||
|
const SizeOfXTTCP = 12
|
||||||
|
|
||||||
|
// Flags in XTTCP.InverseFlags. Corresponding constants are in
|
||||||
|
// include/uapi/linux/netfilter/xt_tcpudp.h.
|
||||||
|
const (
|
||||||
|
// Invert the meaning of SourcePortStart/End.
|
||||||
|
XT_TCP_INV_SRCPT = 0x01
|
||||||
|
// Invert the meaning of DestinationPortStart/End.
|
||||||
|
XT_TCP_INV_DSTPT = 0x02
|
||||||
|
// Invert the meaning of FlagCompare.
|
||||||
|
XT_TCP_INV_FLAGS = 0x04
|
||||||
|
// Invert the meaning of Option.
|
||||||
|
XT_TCP_INV_OPTION = 0x08
|
||||||
|
// Enable all flags.
|
||||||
|
XT_TCP_INV_MASK = 0x0F
|
||||||
|
)
|
||||||
|
|
||||||
|
// XTUDP holds data for matching UDP packets. It corresponds to struct xt_udp
|
||||||
|
// in include/uapi/linux/netfilter/xt_tcpudp.h.
|
||||||
|
//
|
||||||
|
// +marshal
|
||||||
|
type XTUDP struct {
|
||||||
|
// SourcePortStart is the inclusive start of the range of source ports
|
||||||
|
// to which the matcher applies.
|
||||||
|
SourcePortStart uint16
|
||||||
|
|
||||||
|
// SourcePortEnd is the inclusive end of the range of source ports to
|
||||||
|
// which the matcher applies.
|
||||||
|
SourcePortEnd uint16
|
||||||
|
|
||||||
|
// DestinationPortStart is the inclusive start of the destination port
|
||||||
|
// range to which the matcher applies.
|
||||||
|
DestinationPortStart uint16
|
||||||
|
|
||||||
|
// DestinationPortEnd is the inclusive end of the destination port
|
||||||
|
// range to which the matcher applies.
|
||||||
|
DestinationPortEnd uint16
|
||||||
|
|
||||||
|
// InverseFlags flips the meaning of certain fields. See the
|
||||||
|
// TX_UDP_INV_* flags.
|
||||||
|
InverseFlags uint8
|
||||||
|
|
||||||
|
_ uint8
|
||||||
|
}
|
||||||
|
|
||||||
|
// SizeOfXTUDP is the size of an XTUDP.
|
||||||
|
const SizeOfXTUDP = 10
|
||||||
|
|
||||||
|
// Flags in XTUDP.InverseFlags. Corresponding constants are in
|
||||||
|
// include/uapi/linux/netfilter/xt_tcpudp.h.
|
||||||
|
const (
|
||||||
|
// Invert the meaning of SourcePortStart/End.
|
||||||
|
XT_UDP_INV_SRCPT = 0x01
|
||||||
|
// Invert the meaning of DestinationPortStart/End.
|
||||||
|
XT_UDP_INV_DSTPT = 0x02
|
||||||
|
// Enable all flags.
|
||||||
|
XT_UDP_INV_MASK = 0x03
|
||||||
|
)
|
||||||
|
|
||||||
|
// IPTOwnerInfo holds data for matching packets with the owner v0 matcher. It
|
||||||
|
// corresponds to struct ipt_owner_info in libxt_owner.c of iptables binary.
|
||||||
|
//
|
||||||
|
// +marshal
|
||||||
|
type IPTOwnerInfo struct {
|
||||||
|
// UID is user id which created the packet.
|
||||||
|
UID uint32
|
||||||
|
|
||||||
|
// GID is group id which created the packet.
|
||||||
|
GID uint32
|
||||||
|
|
||||||
|
// PID is process id of the process which created the packet.
|
||||||
|
PID uint32
|
||||||
|
|
||||||
|
// SID is session id which created the packet.
|
||||||
|
SID uint32
|
||||||
|
|
||||||
|
// Comm is the command name which created the packet.
|
||||||
|
Comm [16]byte
|
||||||
|
|
||||||
|
// Match is used to match UID/GID of the socket. See the
|
||||||
|
// XT_OWNER_* flags below.
|
||||||
|
Match uint8
|
||||||
|
|
||||||
|
// Invert flips the meaning of Match field.
|
||||||
|
Invert uint8 `marshal:"unaligned"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// SizeOfIPTOwnerInfo is the size of an IPTOwnerInfo.
|
||||||
|
const SizeOfIPTOwnerInfo = 34
|
||||||
|
|
||||||
|
// XTOwnerMatchInfo holds data for matching packets with the owner v1 matcher.
|
||||||
|
// It corresponds to struct xt_owner_match_info in
|
||||||
|
// include/uapi/linux/netfilter/xt_owner.h
|
||||||
|
//
|
||||||
|
// +marshal
|
||||||
|
type XTOwnerMatchInfo struct {
|
||||||
|
UIDMin uint32
|
||||||
|
UIDMax uint32
|
||||||
|
GIDMin uint32
|
||||||
|
GIDMax uint32
|
||||||
|
Match uint8
|
||||||
|
Invert uint8
|
||||||
|
_ [2]byte
|
||||||
|
}
|
||||||
|
|
||||||
|
// SizeOfXTOwnerMatchInfo is the size of an XTOwnerMatchInfo.
|
||||||
|
const SizeOfXTOwnerMatchInfo = 20
|
||||||
|
|
||||||
|
// Flags in IPTOwnerInfo.Match and XTOwnerMatchInfo.Match. Corresponding
|
||||||
|
// constants are in include/uapi/linux/netfilter/xt_owner.h.
|
||||||
|
const (
|
||||||
|
// Match the UID of the packet.
|
||||||
|
XT_OWNER_UID = 1 << 0
|
||||||
|
// Match the GID of the packet.
|
||||||
|
XT_OWNER_GID = 1 << 1
|
||||||
|
// Match if the socket exists for the packet. Forwarded
|
||||||
|
// packets do not have an associated socket.
|
||||||
|
XT_OWNER_SOCKET = 1 << 2
|
||||||
|
)
|
||||||
|
|
||||||
|
// XT_MULTI_PORTS is the maximum number of ports that the
|
||||||
|
// multiport match can handle.
|
||||||
|
const XT_MULTI_PORTS = 15
|
||||||
|
|
||||||
|
// Flags in XTMultiport{,V1}.Flags; values from "enum xt_multiport_flags"
|
||||||
|
// in "include/uapi/linux/netfilter/xt_multiport.h".
|
||||||
|
const (
|
||||||
|
XT_MULTIPORT_SOURCE uint8 = 0x0 // Match against source ports.
|
||||||
|
XT_MULTIPORT_DESTINATION uint8 = 0x1 // Match against destination ports.
|
||||||
|
XT_MULTIPORT_EITHER uint8 = 0x2 // Match against either ports.
|
||||||
|
)
|
||||||
|
|
||||||
|
// XTMultiport holds data for matching packets against a set
|
||||||
|
// of ports. It corresponds to "struct xt_multiport" defined
|
||||||
|
// in "include/uapi/linux/netfilter/xt_multiport.h".
|
||||||
|
//
|
||||||
|
// +marshal
|
||||||
|
type XTMultiport struct {
|
||||||
|
// Flags indicates whether the match applies to
|
||||||
|
// source ports, destination ports, or either, as
|
||||||
|
// defined by "enum xt_multiport_flags".
|
||||||
|
Flags uint8
|
||||||
|
|
||||||
|
// Count is the number of ports in the "Ports"
|
||||||
|
// slice that the match will check. It must be
|
||||||
|
// between 1 and "XT_MULTI_PORTS" (inclusive).
|
||||||
|
Count uint8
|
||||||
|
|
||||||
|
// Ports is the set of ports that will be matched.
|
||||||
|
// Only the first "Count" entries are considered.
|
||||||
|
Ports [XT_MULTI_PORTS]uint16
|
||||||
|
}
|
||||||
|
|
||||||
|
// XTMultiportV1 holds data for matching packets against a set
|
||||||
|
// of ports. It corresponds to "struct xt_multiport_v1" defined
|
||||||
|
// in "include/uapi/linux/netfilter/xt_multiport.h".
|
||||||
|
//
|
||||||
|
// +marshal
|
||||||
|
type XTMultiportV1 struct {
|
||||||
|
// Fields same as "XTMultiport".
|
||||||
|
Flags uint8
|
||||||
|
Count uint8
|
||||||
|
Ports [XT_MULTI_PORTS]uint16
|
||||||
|
|
||||||
|
// Pflags is an array of port-specific flags. Each entry
|
||||||
|
// in "Pflags" corresponds to the port at the same index
|
||||||
|
// in "Ports".
|
||||||
|
Pflags [XT_MULTI_PORTS]uint8
|
||||||
|
|
||||||
|
// Invert is a flag that, if nonzero, indicates
|
||||||
|
// that the match result should be inverted.
|
||||||
|
Invert uint8
|
||||||
|
}
|
||||||
|
|
||||||
|
// SizeOfXTMultiport is the size of XTMultiport (in bytes).
|
||||||
|
const SizeOfXTMultiport = 2 + (XT_MULTI_PORTS * 2)
|
||||||
|
|
||||||
|
// SizeOfXTMultiportV1 is the size of XTMultiportV1 (in bytes).
|
||||||
|
const SizeOfXTMultiportV1 = SizeOfXTMultiport + XT_MULTI_PORTS + 1
|
||||||
24
pkg/abi/linux/netfilter_arp.go
Normal file
24
pkg/abi/linux/netfilter_arp.go
Normal file
|
|
@ -0,0 +1,24 @@
|
||||||
|
// Copyright 2025 The gVisor 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 linux
|
||||||
|
|
||||||
|
// These constants show the hooks ARP packets can be evaluated at.
|
||||||
|
// From include/uapi/linux/netfilter_arp.h.
|
||||||
|
const (
|
||||||
|
NF_ARP_IN = iota
|
||||||
|
NF_ARP_OUT
|
||||||
|
NF_ARP_FORWARD
|
||||||
|
NF_ARP_NUMHOOKS
|
||||||
|
)
|
||||||
41
pkg/abi/linux/netfilter_bridge.go
Normal file
41
pkg/abi/linux/netfilter_bridge.go
Normal file
|
|
@ -0,0 +1,41 @@
|
||||||
|
// Copyright 2024 The gVisor 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 linux
|
||||||
|
|
||||||
|
import "math"
|
||||||
|
|
||||||
|
// Netfilter Bridge Standard Hook Points, from uapi/linux/netfilter_bridge.h.
|
||||||
|
const (
|
||||||
|
NF_BR_PRE_ROUTING = iota
|
||||||
|
NF_BR_LOCAL_IN
|
||||||
|
NF_BR_FORWARD
|
||||||
|
NF_BR_LOCAL_OUT
|
||||||
|
NF_BR_POST_ROUTING
|
||||||
|
NF_BR_BROUTING
|
||||||
|
NF_BR_NUMHOOKS
|
||||||
|
)
|
||||||
|
|
||||||
|
// Netfilter Bridge Standard Hook Priorities, from
|
||||||
|
// uapi/linux/netfilter_bridge.h.
|
||||||
|
const (
|
||||||
|
NF_BR_PRI_FIRST = math.MinInt
|
||||||
|
NF_BR_PRI_NAT_DST_BRIDGED = -300
|
||||||
|
NF_BR_PRI_FILTER_BRIDGED = -200
|
||||||
|
NF_BR_PRI_BRNF = 0
|
||||||
|
NF_BR_PRI_NAT_DST_OTHER = 100
|
||||||
|
NF_BR_PRI_FILTER_OTHER = 200
|
||||||
|
NF_BR_PRI_NAT_SRC = 300
|
||||||
|
NF_BR_PRI_LAST = math.MaxInt
|
||||||
|
)
|
||||||
36
pkg/abi/linux/netfilter_ipv4.go
Normal file
36
pkg/abi/linux/netfilter_ipv4.go
Normal file
|
|
@ -0,0 +1,36 @@
|
||||||
|
// Copyright 2024 The gVisor 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 linux
|
||||||
|
|
||||||
|
import "math"
|
||||||
|
|
||||||
|
// Netfilter IPv4 Standard Hook Priorities, from uapi/linux/netfilter_ipv4.h.
|
||||||
|
const (
|
||||||
|
NF_IP_PRI_FIRST = math.MinInt
|
||||||
|
NF_IP_PRI_RAW_BEFORE_DEFRAG = -450
|
||||||
|
NF_IP_PRI_CONNTRACK_DEFRAG = -400
|
||||||
|
NF_IP_PRI_RAW = -300
|
||||||
|
NF_IP_PRI_SELINUX_FIRST = -225
|
||||||
|
NF_IP_PRI_CONNTRACK = -200
|
||||||
|
NF_IP_PRI_MANGLE = -150
|
||||||
|
NF_IP_PRI_NAT_DST = -100
|
||||||
|
NF_IP_PRI_FILTER = 0
|
||||||
|
NF_IP_PRI_SECURITY = 50
|
||||||
|
NF_IP_PRI_NAT_SRC = 100
|
||||||
|
NF_IP_PRI_SELINUX_LAST = 225
|
||||||
|
NF_IP_PRI_CONNTRACK_HELPER = 300
|
||||||
|
NF_IP_PRI_CONNTRACK_CONFIRM = math.MaxInt
|
||||||
|
NF_IP_PRI_LAST = math.MaxInt
|
||||||
|
)
|
||||||
314
pkg/abi/linux/netfilter_ipv6.go
Normal file
314
pkg/abi/linux/netfilter_ipv6.go
Normal file
|
|
@ -0,0 +1,314 @@
|
||||||
|
// Copyright 2020 The gVisor 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 linux
|
||||||
|
|
||||||
|
import (
|
||||||
|
"math"
|
||||||
|
|
||||||
|
"github.com/sagernet/gvisor/pkg/marshal"
|
||||||
|
"github.com/sagernet/gvisor/pkg/marshal/primitive"
|
||||||
|
)
|
||||||
|
|
||||||
|
// This file contains structures required to support IPv6 netfilter and
|
||||||
|
// ip6tables. Some constants and structs are equal to their IPv4 analogues, and
|
||||||
|
// are only distinguished by context (e.g. whether used on an IPv4 of IPv6
|
||||||
|
// socket).
|
||||||
|
|
||||||
|
// Netfilter IPv6 Standard Hook Priorities, from uapi/linux/netfilter_ipv6.h.
|
||||||
|
const (
|
||||||
|
NF_IP6_PRI_FIRST = math.MinInt
|
||||||
|
NF_IP6_PRI_RAW_BEFORE_DEFRAG = -450
|
||||||
|
NF_IP6_PRI_CONNTRACK_DEFRAG = -400
|
||||||
|
NF_IP6_PRI_RAW = -300
|
||||||
|
NF_IP6_PRI_SELINUX_FIRST = -225
|
||||||
|
NF_IP6_PRI_CONNTRACK = -200
|
||||||
|
NF_IP6_PRI_MANGLE = -150
|
||||||
|
NF_IP6_PRI_NAT_DST = -100
|
||||||
|
NF_IP6_PRI_FILTER = 0
|
||||||
|
NF_IP6_PRI_SECURITY = 50
|
||||||
|
NF_IP6_PRI_NAT_SRC = 100
|
||||||
|
NF_IP6_PRI_SELINUX_LAST = 225
|
||||||
|
NF_IP6_PRI_CONNTRACK_HELPER = 300
|
||||||
|
NF_IP6_PRI_LAST = math.MaxInt
|
||||||
|
)
|
||||||
|
|
||||||
|
// Socket options for SOL_SOCLET. These correspond to values in
|
||||||
|
// include/uapi/linux/netfilter_ipv6/ip6_tables.h.
|
||||||
|
const (
|
||||||
|
IP6T_BASE_CTL = 64
|
||||||
|
IP6T_SO_SET_REPLACE = IPT_BASE_CTL
|
||||||
|
IP6T_SO_SET_ADD_COUNTERS = IPT_BASE_CTL + 1
|
||||||
|
IP6T_SO_SET_MAX = IPT_SO_SET_ADD_COUNTERS
|
||||||
|
|
||||||
|
IP6T_SO_GET_INFO = IPT_BASE_CTL
|
||||||
|
IP6T_SO_GET_ENTRIES = IPT_BASE_CTL + 1
|
||||||
|
IP6T_SO_GET_REVISION_MATCH = IPT_BASE_CTL + 4
|
||||||
|
IP6T_SO_GET_REVISION_TARGET = IPT_BASE_CTL + 5
|
||||||
|
IP6T_SO_GET_MAX = IP6T_SO_GET_REVISION_TARGET
|
||||||
|
)
|
||||||
|
|
||||||
|
// IP6T_ORIGINAL_DST is the ip6tables SOL_IPV6 socket option. Corresponds to
|
||||||
|
// the value in include/uapi/linux/netfilter_ipv6/ip6_tables.h.
|
||||||
|
const IP6T_ORIGINAL_DST = 80
|
||||||
|
|
||||||
|
// IP6TReplace is the argument for the IP6T_SO_SET_REPLACE sockopt. It
|
||||||
|
// corresponds to struct ip6t_replace in
|
||||||
|
// include/uapi/linux/netfilter_ipv6/ip6_tables.h.
|
||||||
|
//
|
||||||
|
// +marshal
|
||||||
|
type IP6TReplace struct {
|
||||||
|
Name TableName
|
||||||
|
ValidHooks uint32
|
||||||
|
NumEntries uint32
|
||||||
|
Size uint32
|
||||||
|
HookEntry [NF_INET_NUMHOOKS]uint32
|
||||||
|
Underflow [NF_INET_NUMHOOKS]uint32
|
||||||
|
NumCounters uint32
|
||||||
|
Counters uint64 // This is really a *XTCounters.
|
||||||
|
// Entries is omitted here because it would cause IP6TReplace to be an
|
||||||
|
// extra byte longer (see http://www.catb.org/esr/structure-packing/).
|
||||||
|
// Entries [0]IP6TEntry
|
||||||
|
}
|
||||||
|
|
||||||
|
// SizeOfIP6TReplace is the size of an IP6TReplace.
|
||||||
|
const SizeOfIP6TReplace = 96
|
||||||
|
|
||||||
|
// KernelIP6TGetEntries is identical to IP6TGetEntries, but includes the
|
||||||
|
// Entrytable field.
|
||||||
|
//
|
||||||
|
// +marshal dynamic
|
||||||
|
type KernelIP6TGetEntries struct {
|
||||||
|
IPTGetEntries
|
||||||
|
Entrytable []KernelIP6TEntry
|
||||||
|
}
|
||||||
|
|
||||||
|
// SizeBytes implements marshal.Marshallable.SizeBytes.
|
||||||
|
func (ke *KernelIP6TGetEntries) SizeBytes() int {
|
||||||
|
res := ke.IPTGetEntries.SizeBytes()
|
||||||
|
for _, entry := range ke.Entrytable {
|
||||||
|
res += entry.SizeBytes()
|
||||||
|
}
|
||||||
|
return res
|
||||||
|
}
|
||||||
|
|
||||||
|
// MarshalBytes implements marshal.Marshallable.MarshalBytes.
|
||||||
|
func (ke *KernelIP6TGetEntries) MarshalBytes(dst []byte) []byte {
|
||||||
|
dst = ke.IPTGetEntries.MarshalUnsafe(dst)
|
||||||
|
for i := range ke.Entrytable {
|
||||||
|
dst = ke.Entrytable[i].MarshalBytes(dst)
|
||||||
|
}
|
||||||
|
return dst
|
||||||
|
}
|
||||||
|
|
||||||
|
// UnmarshalBytes implements marshal.Marshallable.UnmarshalBytes.
|
||||||
|
func (ke *KernelIP6TGetEntries) UnmarshalBytes(src []byte) []byte {
|
||||||
|
src = ke.IPTGetEntries.UnmarshalUnsafe(src)
|
||||||
|
for i := range ke.Entrytable {
|
||||||
|
src = ke.Entrytable[i].UnmarshalBytes(src)
|
||||||
|
}
|
||||||
|
return src
|
||||||
|
}
|
||||||
|
|
||||||
|
var _ marshal.Marshallable = (*KernelIP6TGetEntries)(nil)
|
||||||
|
|
||||||
|
// IP6TEntry is an iptables rule. It corresponds to struct ip6t_entry in
|
||||||
|
// include/uapi/linux/netfilter_ipv6/ip6_tables.h.
|
||||||
|
//
|
||||||
|
// +marshal
|
||||||
|
type IP6TEntry struct {
|
||||||
|
// IPv6 is used to filter packets based on the IPv6 header.
|
||||||
|
IPv6 IP6TIP
|
||||||
|
|
||||||
|
// NFCache relates to kernel-internal caching and isn't used by
|
||||||
|
// userspace.
|
||||||
|
NFCache uint32
|
||||||
|
|
||||||
|
// TargetOffset is the byte offset from the beginning of this IPTEntry
|
||||||
|
// to the start of the entry's target.
|
||||||
|
TargetOffset uint16
|
||||||
|
|
||||||
|
// NextOffset is the byte offset from the beginning of this IPTEntry to
|
||||||
|
// the start of the next entry. It is thus also the size of the entry.
|
||||||
|
NextOffset uint16
|
||||||
|
|
||||||
|
// Comeback is a return pointer. It is not used by userspace.
|
||||||
|
Comeback uint32
|
||||||
|
|
||||||
|
_ [4]byte
|
||||||
|
|
||||||
|
// Counters holds the packet and byte counts for this rule.
|
||||||
|
Counters XTCounters
|
||||||
|
|
||||||
|
// Elems holds the data for all this rule's matches followed by the
|
||||||
|
// target. It is variable length -- users have to iterate over any
|
||||||
|
// matches and use TargetOffset and NextOffset to make sense of the
|
||||||
|
// data.
|
||||||
|
//
|
||||||
|
// Elems is omitted here because it would cause IPTEntry to be an extra
|
||||||
|
// byte larger (see http://www.catb.org/esr/structure-packing/).
|
||||||
|
//
|
||||||
|
// Elems [0]byte
|
||||||
|
}
|
||||||
|
|
||||||
|
// SizeOfIP6TEntry is the size of an IP6TEntry.
|
||||||
|
const SizeOfIP6TEntry = 168
|
||||||
|
|
||||||
|
// KernelIP6TEntry is identical to IP6TEntry, but includes the Elems field.
|
||||||
|
//
|
||||||
|
// +marshal dynamic
|
||||||
|
type KernelIP6TEntry struct {
|
||||||
|
Entry IP6TEntry
|
||||||
|
|
||||||
|
// Elems holds the data for all this rule's matches followed by the
|
||||||
|
// target. It is variable length -- users have to iterate over any
|
||||||
|
// matches and use TargetOffset and NextOffset to make sense of the
|
||||||
|
// data.
|
||||||
|
Elems primitive.ByteSlice
|
||||||
|
}
|
||||||
|
|
||||||
|
// SizeBytes implements marshal.Marshallable.SizeBytes.
|
||||||
|
func (ke *KernelIP6TEntry) SizeBytes() int {
|
||||||
|
return ke.Entry.SizeBytes() + ke.Elems.SizeBytes()
|
||||||
|
}
|
||||||
|
|
||||||
|
// MarshalBytes implements marshal.Marshallable.MarshalBytes.
|
||||||
|
func (ke *KernelIP6TEntry) MarshalBytes(dst []byte) []byte {
|
||||||
|
dst = ke.Entry.MarshalUnsafe(dst)
|
||||||
|
return ke.Elems.MarshalBytes(dst)
|
||||||
|
}
|
||||||
|
|
||||||
|
// UnmarshalBytes implements marshal.Marshallable.UnmarshalBytes.
|
||||||
|
func (ke *KernelIP6TEntry) UnmarshalBytes(src []byte) []byte {
|
||||||
|
src = ke.Entry.UnmarshalUnsafe(src)
|
||||||
|
return ke.Elems.UnmarshalBytes(src)
|
||||||
|
}
|
||||||
|
|
||||||
|
var _ marshal.Marshallable = (*KernelIP6TEntry)(nil)
|
||||||
|
|
||||||
|
// IP6TIP contains information for matching a packet's IP header.
|
||||||
|
// It corresponds to struct ip6t_ip6 in
|
||||||
|
// include/uapi/linux/netfilter_ipv6/ip6_tables.h.
|
||||||
|
//
|
||||||
|
// +marshal
|
||||||
|
type IP6TIP struct {
|
||||||
|
// Src is the source IP address.
|
||||||
|
Src Inet6Addr
|
||||||
|
|
||||||
|
// Dst is the destination IP address.
|
||||||
|
Dst Inet6Addr
|
||||||
|
|
||||||
|
// SrcMask is the source IP mask.
|
||||||
|
SrcMask Inet6Addr
|
||||||
|
|
||||||
|
// DstMask is the destination IP mask.
|
||||||
|
DstMask Inet6Addr
|
||||||
|
|
||||||
|
// InputInterface is the input network interface.
|
||||||
|
InputInterface [IFNAMSIZ]byte
|
||||||
|
|
||||||
|
// OutputInterface is the output network interface.
|
||||||
|
OutputInterface [IFNAMSIZ]byte
|
||||||
|
|
||||||
|
// InputInterfaceMask is the input interface mask.
|
||||||
|
InputInterfaceMask [IFNAMSIZ]byte
|
||||||
|
|
||||||
|
// OuputInterfaceMask is the output interface mask.
|
||||||
|
OutputInterfaceMask [IFNAMSIZ]byte
|
||||||
|
|
||||||
|
// Protocol is the transport protocol.
|
||||||
|
Protocol uint16
|
||||||
|
|
||||||
|
// TOS matches TOS flags when Flags indicates filtering by TOS.
|
||||||
|
TOS uint8
|
||||||
|
|
||||||
|
// Flags define matching behavior for the IP header.
|
||||||
|
Flags uint8
|
||||||
|
|
||||||
|
// InverseFlags invert the meaning of fields in struct IPTIP. See the
|
||||||
|
// IP6T_INV_* flags.
|
||||||
|
InverseFlags uint8
|
||||||
|
|
||||||
|
// Linux defines in6_addr (Inet6Addr for us) as the union of a
|
||||||
|
// 16-element byte array and a 4-element 32-bit integer array, so the
|
||||||
|
// whole struct is 4-byte aligned.
|
||||||
|
_ [3]byte
|
||||||
|
}
|
||||||
|
|
||||||
|
// SizeOfIP6TIP is the size of an IP6 header.
|
||||||
|
const SizeOfIP6TIP = 136
|
||||||
|
|
||||||
|
// Flags in IP6TIP.Flags. Corresponding constants are in
|
||||||
|
// include/uapi/linux/netfilter_ipv6/ip6_tables.h.
|
||||||
|
const (
|
||||||
|
// Whether to check the Protocol field.
|
||||||
|
IP6T_F_PROTO = 0x01
|
||||||
|
// Whether to match the TOS field.
|
||||||
|
IP6T_F_TOS = 0x02
|
||||||
|
// Indicates that the jump target is an absolute GOTO, not an offset.
|
||||||
|
IP6T_F_GOTO = 0x04
|
||||||
|
// Enables all flags.
|
||||||
|
IP6T_F_MASK = 0x07
|
||||||
|
)
|
||||||
|
|
||||||
|
// Flags in IP6TIP.InverseFlags. Corresponding constants are in
|
||||||
|
// include/uapi/linux/netfilter_ipv6/ip6_tables.h.
|
||||||
|
const (
|
||||||
|
// Invert the meaning of InputInterface.
|
||||||
|
IP6T_INV_VIA_IN = 0x01
|
||||||
|
// Invert the meaning of OutputInterface.
|
||||||
|
IP6T_INV_VIA_OUT = 0x02
|
||||||
|
// Invert the meaning of TOS.
|
||||||
|
IP6T_INV_TOS = 0x04
|
||||||
|
// Invert the meaning of Src.
|
||||||
|
IP6T_INV_SRCIP = 0x08
|
||||||
|
// Invert the meaning of Dst.
|
||||||
|
IP6T_INV_DSTIP = 0x10
|
||||||
|
// Invert the meaning of the IPT_F_FRAG flag.
|
||||||
|
IP6T_INV_FRAG = 0x20
|
||||||
|
// Enable all flags.
|
||||||
|
IP6T_INV_MASK = 0x7F
|
||||||
|
)
|
||||||
|
|
||||||
|
// NFNATRange corresponds to struct nf_nat_range in
|
||||||
|
// include/uapi/linux/netfilter/nf_nat.h.
|
||||||
|
//
|
||||||
|
// +marshal
|
||||||
|
type NFNATRange struct {
|
||||||
|
Flags uint32
|
||||||
|
MinAddr Inet6Addr
|
||||||
|
MaxAddr Inet6Addr
|
||||||
|
MinProto uint16 // Network byte order.
|
||||||
|
MaxProto uint16 // Network byte order.
|
||||||
|
}
|
||||||
|
|
||||||
|
// SizeOfNFNATRange is the size of NFNATRange.
|
||||||
|
const SizeOfNFNATRange = 40
|
||||||
|
|
||||||
|
// NFNATRange2 corresponds to struct nf_nat_range2 in
|
||||||
|
// include/uapi/linux/netfilter/nf_nat.h.
|
||||||
|
//
|
||||||
|
// +marshal
|
||||||
|
type NFNATRange2 struct {
|
||||||
|
Flags uint32
|
||||||
|
MinAddr Inet6Addr
|
||||||
|
MaxAddr Inet6Addr
|
||||||
|
MinProto uint16 // Network byte order.
|
||||||
|
MaxProto uint16 // Network byte order.
|
||||||
|
BaseProto uint16 // Network byte order.
|
||||||
|
_ [6]byte
|
||||||
|
}
|
||||||
|
|
||||||
|
// SizeOfNFNATRange2 is the size of NFNATRange2.
|
||||||
|
const SizeOfNFNATRange2 = 48
|
||||||
159
pkg/abi/linux/netlink.go
Normal file
159
pkg/abi/linux/netlink.go
Normal file
|
|
@ -0,0 +1,159 @@
|
||||||
|
// Copyright 2018 The gVisor 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 linux
|
||||||
|
|
||||||
|
// Netlink protocols, from uapi/linux/netlink.h.
|
||||||
|
const (
|
||||||
|
NETLINK_ROUTE = 0
|
||||||
|
NETLINK_UNUSED = 1
|
||||||
|
NETLINK_USERSOCK = 2
|
||||||
|
NETLINK_FIREWALL = 3
|
||||||
|
NETLINK_SOCK_DIAG = 4
|
||||||
|
NETLINK_NFLOG = 5
|
||||||
|
NETLINK_XFRM = 6
|
||||||
|
NETLINK_SELINUX = 7
|
||||||
|
NETLINK_ISCSI = 8
|
||||||
|
NETLINK_AUDIT = 9
|
||||||
|
NETLINK_FIB_LOOKUP = 10
|
||||||
|
NETLINK_CONNECTOR = 11
|
||||||
|
NETLINK_NETFILTER = 12
|
||||||
|
NETLINK_IP6_FW = 13
|
||||||
|
NETLINK_DNRTMSG = 14
|
||||||
|
NETLINK_KOBJECT_UEVENT = 15
|
||||||
|
NETLINK_GENERIC = 16
|
||||||
|
NETLINK_SCSITRANSPORT = 18
|
||||||
|
NETLINK_ECRYPTFS = 19
|
||||||
|
NETLINK_RDMA = 20
|
||||||
|
NETLINK_CRYPTO = 21
|
||||||
|
)
|
||||||
|
|
||||||
|
// SockAddrNetlink is struct sockaddr_nl, from uapi/linux/netlink.h.
|
||||||
|
//
|
||||||
|
// +marshal
|
||||||
|
type SockAddrNetlink struct {
|
||||||
|
Family uint16
|
||||||
|
_ uint16
|
||||||
|
PortID uint32
|
||||||
|
Groups uint32
|
||||||
|
}
|
||||||
|
|
||||||
|
// SockAddrNetlinkSize is the size of SockAddrNetlink.
|
||||||
|
const SockAddrNetlinkSize = 12
|
||||||
|
|
||||||
|
// NetlinkMessageHeader is struct nlmsghdr, from uapi/linux/netlink.h.
|
||||||
|
//
|
||||||
|
// +marshal
|
||||||
|
type NetlinkMessageHeader struct {
|
||||||
|
Length uint32
|
||||||
|
Type uint16
|
||||||
|
Flags uint16
|
||||||
|
Seq uint32
|
||||||
|
PortID uint32
|
||||||
|
}
|
||||||
|
|
||||||
|
// NetlinkMessageHeaderSize is the size of NetlinkMessageHeader.
|
||||||
|
const NetlinkMessageHeaderSize = 16
|
||||||
|
|
||||||
|
// Netlink message header flag values, from uapi/linux/netlink.h.
|
||||||
|
const (
|
||||||
|
NLM_F_REQUEST = 0x1
|
||||||
|
NLM_F_MULTI = 0x2
|
||||||
|
NLM_F_ACK = 0x4
|
||||||
|
NLM_F_ECHO = 0x8
|
||||||
|
NLM_F_DUMP_INTR = 0x10
|
||||||
|
)
|
||||||
|
|
||||||
|
// Netlink message header flags for GET requests, from uapi/linux/netlink.h.
|
||||||
|
const (
|
||||||
|
NLM_F_ROOT = 0x100
|
||||||
|
NLM_F_MATCH = 0x200
|
||||||
|
NLM_F_ATOMIC = 0x400
|
||||||
|
NLM_F_DUMP = NLM_F_ROOT | NLM_F_MATCH
|
||||||
|
)
|
||||||
|
|
||||||
|
// Netlink message header flags for NEW requests, from uapi/linux/netlink.h.
|
||||||
|
const (
|
||||||
|
NLM_F_REPLACE = 0x100
|
||||||
|
NLM_F_EXCL = 0x200
|
||||||
|
NLM_F_CREATE = 0x400
|
||||||
|
NLM_F_APPEND = 0x800
|
||||||
|
)
|
||||||
|
|
||||||
|
// Netlink message header flags for DELETE requests, from uapi/linux/netlink.h.
|
||||||
|
const (
|
||||||
|
NLM_F_NONREC = 0x100
|
||||||
|
NLM_F_BULK = 0x200
|
||||||
|
)
|
||||||
|
|
||||||
|
// Standard netlink message types, from uapi/linux/netlink.h.
|
||||||
|
const (
|
||||||
|
NLMSG_NOOP = 0x1
|
||||||
|
NLMSG_ERROR = 0x2
|
||||||
|
NLMSG_DONE = 0x3
|
||||||
|
NLMSG_OVERRUN = 0x4
|
||||||
|
|
||||||
|
// NLMSG_MIN_TYPE is the first value for protocol-level types.
|
||||||
|
NLMSG_MIN_TYPE = 0x10
|
||||||
|
)
|
||||||
|
|
||||||
|
// NLMSG_ALIGNTO is the alignment of netlink messages, from
|
||||||
|
// uapi/linux/netlink.h.
|
||||||
|
const NLMSG_ALIGNTO = 4
|
||||||
|
|
||||||
|
// NetlinkAttrHeader is the header of a netlink attribute, followed by payload.
|
||||||
|
//
|
||||||
|
// This is struct nlattr, from uapi/linux/netlink.h.
|
||||||
|
//
|
||||||
|
// +marshal
|
||||||
|
type NetlinkAttrHeader struct {
|
||||||
|
Length uint16
|
||||||
|
Type uint16
|
||||||
|
}
|
||||||
|
|
||||||
|
// Netlink attribute flags, from uapi/linux/netlink.h.
|
||||||
|
const (
|
||||||
|
NLA_F_NESTED uint16 = 1 << 15
|
||||||
|
NLA_F_NET_BYTEORDER = 1 << 14
|
||||||
|
NLA_TYPE_MASK = ^(NLA_F_NESTED | NLA_F_NET_BYTEORDER)
|
||||||
|
)
|
||||||
|
|
||||||
|
// NetlinkAttrHeaderSize is the size of NetlinkAttrHeader.
|
||||||
|
const NetlinkAttrHeaderSize = 4
|
||||||
|
|
||||||
|
// NLA_ALIGNTO is the alignment of netlink attributes, from
|
||||||
|
// uapi/linux/netlink.h.
|
||||||
|
const NLA_ALIGNTO = 4
|
||||||
|
|
||||||
|
// Socket options, from uapi/linux/netlink.h.
|
||||||
|
const (
|
||||||
|
NETLINK_ADD_MEMBERSHIP = 1
|
||||||
|
NETLINK_DROP_MEMBERSHIP = 2
|
||||||
|
NETLINK_PKTINFO = 3
|
||||||
|
NETLINK_BROADCAST_ERROR = 4
|
||||||
|
NETLINK_NO_ENOBUFS = 5
|
||||||
|
NETLINK_LISTEN_ALL_NSID = 8
|
||||||
|
NETLINK_LIST_MEMBERSHIPS = 9
|
||||||
|
NETLINK_CAP_ACK = 10
|
||||||
|
NETLINK_EXT_ACK = 11
|
||||||
|
NETLINK_DUMP_STRICT_CHK = 12
|
||||||
|
)
|
||||||
|
|
||||||
|
// NetlinkErrorMessage is struct nlmsgerr, from uapi/linux/netlink.h.
|
||||||
|
//
|
||||||
|
// +marshal
|
||||||
|
type NetlinkErrorMessage struct {
|
||||||
|
Error int32
|
||||||
|
Header NetlinkMessageHeader
|
||||||
|
}
|
||||||
92
pkg/abi/linux/netlink_netfilter.go
Normal file
92
pkg/abi/linux/netlink_netfilter.go
Normal file
|
|
@ -0,0 +1,92 @@
|
||||||
|
// Copyright 2025 The gVisor 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 linux
|
||||||
|
|
||||||
|
// Group describes Netlink Netfilter groups, from uapi/linux/netfilter/nfnetlink.h.
|
||||||
|
// Users bind to specific groups to receive processing logs from those groups.
|
||||||
|
type Group uint16
|
||||||
|
|
||||||
|
// Netlink Netfilter groups.
|
||||||
|
const (
|
||||||
|
NFNLGPR_NONE Group = iota
|
||||||
|
NFNLGRP_CONNTRACK_NEW
|
||||||
|
NFNLGRP_CONNTRACK_UPDATE
|
||||||
|
NFNLGRP_CONNTRACK_DESTROY
|
||||||
|
NFNLGRP_CONNTRACK_EXP_NEW
|
||||||
|
NFNLGRP_CONNTRACK_EXP_UPDATE
|
||||||
|
NFNLGRP_CONNTRACK_EXP_DESTROY
|
||||||
|
NFNLGRP_NFTABLES
|
||||||
|
NFNLGRP_ACCT_QUOTA
|
||||||
|
NFNLGRP_NFTRACE
|
||||||
|
__NFNLGRP_MAX
|
||||||
|
NFNLGRP_MAX = __NFNLGRP_MAX - 1
|
||||||
|
)
|
||||||
|
|
||||||
|
// NetFilterGenMsg describes the netlink netfilter genmsg message, from uapi/linux/netfilter/nfnetlink.h.
|
||||||
|
//
|
||||||
|
// +marshal
|
||||||
|
type NetFilterGenMsg struct {
|
||||||
|
Family uint8
|
||||||
|
Version uint8
|
||||||
|
ResourceID uint16
|
||||||
|
}
|
||||||
|
|
||||||
|
// SizeOfNetfilterGenMsg is the size of the netlink netfilter genmsg message.
|
||||||
|
const SizeOfNetfilterGenMsg = 4
|
||||||
|
|
||||||
|
// NFNETLINK_V0 is the default version of the netlink netfilter.
|
||||||
|
const NFNETLINK_V0 = 0
|
||||||
|
|
||||||
|
// Netlink Netfilter subsystem IDs, from uapi/linux/netfilter/nfnetlink.h.
|
||||||
|
const (
|
||||||
|
NFNL_SUBSYS_NONE = iota
|
||||||
|
NFNL_SUBSYS_CTNETLINK
|
||||||
|
NFNL_SUBSYS_CTNETLINK_EXP
|
||||||
|
NFNL_SUBSYS_QUEUE
|
||||||
|
NFNL_SUBSYS_ULOG
|
||||||
|
NFNL_SUBSYS_OSF
|
||||||
|
NFNL_SUBSYS_IPSET
|
||||||
|
NFNL_SUBSYS_ACCT
|
||||||
|
NFNL_SUBSYS_CTNETLINK_TIMEOUT
|
||||||
|
NFNL_SUBSYS_CTHELPER
|
||||||
|
NFNL_SUBSYS_NFTABLES
|
||||||
|
NFNL_SUBSYS_NFT_COMPAT
|
||||||
|
NFNL_SUBSYS_HOOK
|
||||||
|
NFNL_SUBSYS_COUNT
|
||||||
|
)
|
||||||
|
|
||||||
|
// NetFilterSubsysID returns the Netfilter Subsystem ID from the netlink message header.
|
||||||
|
func (hdr *NetlinkMessageHeader) NetFilterSubsysID() uint16 {
|
||||||
|
return (hdr.Type & 0xff00) >> 8
|
||||||
|
}
|
||||||
|
|
||||||
|
// NetFilterMsgType returns the Netfilter Message Type from the netlink message header.
|
||||||
|
func (hdr *NetlinkMessageHeader) NetFilterMsgType() NfTableMsgType {
|
||||||
|
return NfTableMsgType(hdr.Type & 0x00ff)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Reserved control Netlink Netfilter messages, from uapi/linux/netfilter/nfnetlink.h.
|
||||||
|
const (
|
||||||
|
NFNL_MSG_BATCH_BEGIN = NLMSG_MIN_TYPE
|
||||||
|
NFNL_MSG_BATCH_END = NLMSG_MIN_TYPE + 1
|
||||||
|
)
|
||||||
|
|
||||||
|
// Netlink Netfilter batch attributes.
|
||||||
|
const (
|
||||||
|
NFNL_BATCH_UNSPEC = iota
|
||||||
|
NFNL_BATCH_GENID
|
||||||
|
__NFNL_BATCH_MAX
|
||||||
|
NFNL_BATCH_MAX = __NFNL_BATCH_MAX - 1
|
||||||
|
)
|
||||||
377
pkg/abi/linux/netlink_route.go
Normal file
377
pkg/abi/linux/netlink_route.go
Normal file
|
|
@ -0,0 +1,377 @@
|
||||||
|
// Copyright 2018 The gVisor 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 linux
|
||||||
|
|
||||||
|
// Netlink message types for NETLINK_ROUTE sockets, from uapi/linux/rtnetlink.h.
|
||||||
|
const (
|
||||||
|
RTM_NEWLINK = 16
|
||||||
|
RTM_DELLINK = 17
|
||||||
|
RTM_GETLINK = 18
|
||||||
|
RTM_SETLINK = 19
|
||||||
|
|
||||||
|
RTM_NEWADDR = 20
|
||||||
|
RTM_DELADDR = 21
|
||||||
|
RTM_GETADDR = 22
|
||||||
|
|
||||||
|
RTM_NEWROUTE = 24
|
||||||
|
RTM_DELROUTE = 25
|
||||||
|
RTM_GETROUTE = 26
|
||||||
|
|
||||||
|
RTM_NEWNEIGH = 28
|
||||||
|
RTM_DELNEIGH = 29
|
||||||
|
RTM_GETNEIGH = 30
|
||||||
|
|
||||||
|
RTM_NEWRULE = 32
|
||||||
|
RTM_DELRULE = 33
|
||||||
|
RTM_GETRULE = 34
|
||||||
|
|
||||||
|
RTM_NEWQDISC = 36
|
||||||
|
RTM_DELQDISC = 37
|
||||||
|
RTM_GETQDISC = 38
|
||||||
|
|
||||||
|
RTM_NEWTCLASS = 40
|
||||||
|
RTM_DELTCLASS = 41
|
||||||
|
RTM_GETTCLASS = 42
|
||||||
|
|
||||||
|
RTM_NEWTFILTER = 44
|
||||||
|
RTM_DELTFILTER = 45
|
||||||
|
RTM_GETTFILTER = 46
|
||||||
|
|
||||||
|
RTM_NEWACTION = 48
|
||||||
|
RTM_DELACTION = 49
|
||||||
|
RTM_GETACTION = 50
|
||||||
|
|
||||||
|
RTM_NEWPREFIX = 52
|
||||||
|
|
||||||
|
RTM_GETMULTICAST = 58
|
||||||
|
|
||||||
|
RTM_GETANYCAST = 62
|
||||||
|
|
||||||
|
RTM_NEWNEIGHTBL = 64
|
||||||
|
RTM_GETNEIGHTBL = 66
|
||||||
|
RTM_SETNEIGHTBL = 67
|
||||||
|
|
||||||
|
RTM_NEWNDUSEROPT = 68
|
||||||
|
|
||||||
|
RTM_NEWADDRLABEL = 72
|
||||||
|
RTM_DELADDRLABEL = 73
|
||||||
|
RTM_GETADDRLABEL = 74
|
||||||
|
|
||||||
|
RTM_GETDCB = 78
|
||||||
|
RTM_SETDCB = 79
|
||||||
|
|
||||||
|
RTM_NEWNETCONF = 80
|
||||||
|
RTM_GETNETCONF = 82
|
||||||
|
|
||||||
|
RTM_NEWMDB = 84
|
||||||
|
RTM_DELMDB = 85
|
||||||
|
RTM_GETMDB = 86
|
||||||
|
|
||||||
|
RTM_NEWNSID = 88
|
||||||
|
RTM_DELNSID = 89
|
||||||
|
RTM_GETNSID = 90
|
||||||
|
)
|
||||||
|
|
||||||
|
// InterfaceInfoMessage is struct ifinfomsg, from uapi/linux/rtnetlink.h.
|
||||||
|
//
|
||||||
|
// +marshal
|
||||||
|
type InterfaceInfoMessage struct {
|
||||||
|
Family uint8
|
||||||
|
_ uint8
|
||||||
|
Type uint16
|
||||||
|
Index int32
|
||||||
|
Flags uint32
|
||||||
|
Change uint32
|
||||||
|
}
|
||||||
|
|
||||||
|
// InterfaceInfoMessageSize is the size of InterfaceInfoMessage.
|
||||||
|
const InterfaceInfoMessageSize = 16
|
||||||
|
|
||||||
|
// Interface flags, from uapi/linux/if.h.
|
||||||
|
const (
|
||||||
|
IFF_UP = 1 << 0
|
||||||
|
IFF_BROADCAST = 1 << 1
|
||||||
|
IFF_DEBUG = 1 << 2
|
||||||
|
IFF_LOOPBACK = 1 << 3
|
||||||
|
IFF_POINTOPOINT = 1 << 4
|
||||||
|
IFF_NOTRAILERS = 1 << 5
|
||||||
|
IFF_RUNNING = 1 << 6
|
||||||
|
IFF_NOARP = 1 << 7
|
||||||
|
IFF_PROMISC = 1 << 8
|
||||||
|
IFF_ALLMULTI = 1 << 9
|
||||||
|
IFF_MASTER = 1 << 10
|
||||||
|
IFF_SLAVE = 1 << 11
|
||||||
|
IFF_MULTICAST = 1 << 12
|
||||||
|
IFF_PORTSEL = 1 << 13
|
||||||
|
IFF_AUTOMEDIA = 1 << 14
|
||||||
|
IFF_DYNAMIC = 1 << 15
|
||||||
|
IFF_LOWER_UP = 1 << 16
|
||||||
|
IFF_DORMANT = 1 << 17
|
||||||
|
IFF_ECHO = 1 << 18
|
||||||
|
)
|
||||||
|
|
||||||
|
// Interface link attributes, from uapi/linux/if_link.h.
|
||||||
|
const (
|
||||||
|
IFLA_UNSPEC = 0
|
||||||
|
IFLA_ADDRESS = 1
|
||||||
|
IFLA_BROADCAST = 2
|
||||||
|
IFLA_IFNAME = 3
|
||||||
|
IFLA_MTU = 4
|
||||||
|
IFLA_LINK = 5
|
||||||
|
IFLA_QDISC = 6
|
||||||
|
IFLA_STATS = 7
|
||||||
|
IFLA_COST = 8
|
||||||
|
IFLA_PRIORITY = 9
|
||||||
|
IFLA_MASTER = 10
|
||||||
|
IFLA_WIRELESS = 11
|
||||||
|
IFLA_PROTINFO = 12
|
||||||
|
IFLA_TXQLEN = 13
|
||||||
|
IFLA_MAP = 14
|
||||||
|
IFLA_WEIGHT = 15
|
||||||
|
IFLA_OPERSTATE = 16
|
||||||
|
IFLA_LINKMODE = 17
|
||||||
|
IFLA_LINKINFO = 18
|
||||||
|
IFLA_NET_NS_PID = 19
|
||||||
|
IFLA_IFALIAS = 20
|
||||||
|
IFLA_NUM_VF = 21
|
||||||
|
IFLA_VFINFO_LIST = 22
|
||||||
|
IFLA_STATS64 = 23
|
||||||
|
IFLA_VF_PORTS = 24
|
||||||
|
IFLA_PORT_SELF = 25
|
||||||
|
IFLA_AF_SPEC = 26
|
||||||
|
IFLA_GROUP = 27
|
||||||
|
IFLA_NET_NS_FD = 28
|
||||||
|
IFLA_EXT_MASK = 29
|
||||||
|
IFLA_PROMISCUITY = 30
|
||||||
|
IFLA_NUM_TX_QUEUES = 31
|
||||||
|
IFLA_NUM_RX_QUEUES = 32
|
||||||
|
IFLA_CARRIER = 33
|
||||||
|
IFLA_PHYS_PORT_ID = 34
|
||||||
|
IFLA_CARRIER_CHANGES = 35
|
||||||
|
IFLA_PHYS_SWITCH_ID = 36
|
||||||
|
IFLA_LINK_NETNSID = 37
|
||||||
|
IFLA_PHYS_PORT_NAME = 38
|
||||||
|
IFLA_PROTO_DOWN = 39
|
||||||
|
IFLA_GSO_MAX_SEGS = 40
|
||||||
|
IFLA_GSO_MAX_SIZE = 41
|
||||||
|
)
|
||||||
|
|
||||||
|
// Interface link info attributes, from uapi/linux/if_link.h.
|
||||||
|
const (
|
||||||
|
IFLA_INFO_UNSPEC = 0
|
||||||
|
IFLA_INFO_KIND = 1
|
||||||
|
IFLA_INFO_DATA = 2
|
||||||
|
IFLA_INFO_XSTATS = 3
|
||||||
|
IFLA_INFO_SLAVE_KIND = 4
|
||||||
|
IFLA_INFO_SLAVE_DATA = 5
|
||||||
|
)
|
||||||
|
|
||||||
|
// Virtuall ethernet attributes, from uapi/linux/veth.h.
|
||||||
|
const (
|
||||||
|
VETH_INFO_PEER = 1
|
||||||
|
)
|
||||||
|
|
||||||
|
// InterfaceAddrMessage is struct ifaddrmsg, from uapi/linux/if_addr.h.
|
||||||
|
//
|
||||||
|
// +marshal
|
||||||
|
type InterfaceAddrMessage struct {
|
||||||
|
Family uint8
|
||||||
|
PrefixLen uint8
|
||||||
|
Flags uint8
|
||||||
|
Scope uint8
|
||||||
|
Index uint32
|
||||||
|
}
|
||||||
|
|
||||||
|
// InterfaceAddrMessageSize is the size of InterfaceAddrMessage.
|
||||||
|
const InterfaceAddrMessageSize = 8
|
||||||
|
|
||||||
|
// Interface attributes, from uapi/linux/if_addr.h.
|
||||||
|
const (
|
||||||
|
IFA_UNSPEC = 0
|
||||||
|
IFA_ADDRESS = 1
|
||||||
|
IFA_LOCAL = 2
|
||||||
|
IFA_LABEL = 3
|
||||||
|
IFA_BROADCAST = 4
|
||||||
|
IFA_ANYCAST = 5
|
||||||
|
IFA_CACHEINFO = 6
|
||||||
|
IFA_MULTICAST = 7
|
||||||
|
IFA_FLAGS = 8
|
||||||
|
)
|
||||||
|
|
||||||
|
// Device types, from uapi/linux/if_arp.h.
|
||||||
|
const (
|
||||||
|
ARPHRD_NONE = 65534
|
||||||
|
ARPHRD_ETHER = 1
|
||||||
|
ARPHRD_LOOPBACK = 772
|
||||||
|
)
|
||||||
|
|
||||||
|
// RouteMessage is struct rtmsg, from uapi/linux/rtnetlink.h.
|
||||||
|
//
|
||||||
|
// +marshal
|
||||||
|
type RouteMessage struct {
|
||||||
|
Family uint8
|
||||||
|
DstLen uint8
|
||||||
|
SrcLen uint8
|
||||||
|
TOS uint8
|
||||||
|
|
||||||
|
Table uint8
|
||||||
|
Protocol uint8
|
||||||
|
Scope uint8
|
||||||
|
Type uint8
|
||||||
|
|
||||||
|
Flags uint32
|
||||||
|
}
|
||||||
|
|
||||||
|
// SizeOfRouteMessage is the size of RouteMessage.
|
||||||
|
const SizeOfRouteMessage = 12
|
||||||
|
|
||||||
|
// Route types, from uapi/linux/rtnetlink.h.
|
||||||
|
const (
|
||||||
|
// RTN_UNSPEC represents an unspecified route type.
|
||||||
|
RTN_UNSPEC = 0
|
||||||
|
|
||||||
|
// RTN_UNICAST represents a unicast route.
|
||||||
|
RTN_UNICAST = 1
|
||||||
|
|
||||||
|
// RTN_LOCAL represents a route that is accepted locally.
|
||||||
|
RTN_LOCAL = 2
|
||||||
|
|
||||||
|
// RTN_BROADCAST represents a broadcast route (Traffic is accepted locally
|
||||||
|
// as broadcast, and sent as broadcast).
|
||||||
|
RTN_BROADCAST = 3
|
||||||
|
|
||||||
|
// RTN_ANYCAST represents a anycast route (Traffic is accepted locally as
|
||||||
|
// broadcast but sent as unicast).
|
||||||
|
RTN_ANYCAST = 6
|
||||||
|
|
||||||
|
// RTN_MULTICAST represents a multicast route.
|
||||||
|
RTN_MULTICAST = 5
|
||||||
|
|
||||||
|
// RTN_BLACKHOLE represents a route where all traffic is dropped.
|
||||||
|
RTN_BLACKHOLE = 6
|
||||||
|
|
||||||
|
// RTN_UNREACHABLE represents a route where the destination is unreachable.
|
||||||
|
RTN_UNREACHABLE = 7
|
||||||
|
|
||||||
|
RTN_PROHIBIT = 8
|
||||||
|
RTN_THROW = 9
|
||||||
|
RTN_NAT = 10
|
||||||
|
RTN_XRESOLVE = 11
|
||||||
|
)
|
||||||
|
|
||||||
|
// Route protocols/origins, from uapi/linux/rtnetlink.h.
|
||||||
|
const (
|
||||||
|
RTPROT_UNSPEC = 0
|
||||||
|
RTPROT_REDIRECT = 1
|
||||||
|
RTPROT_KERNEL = 2
|
||||||
|
RTPROT_BOOT = 3
|
||||||
|
RTPROT_STATIC = 4
|
||||||
|
RTPROT_GATED = 8
|
||||||
|
RTPROT_RA = 9
|
||||||
|
RTPROT_MRT = 10
|
||||||
|
RTPROT_ZEBRA = 11
|
||||||
|
RTPROT_BIRD = 12
|
||||||
|
RTPROT_DNROUTED = 13
|
||||||
|
RTPROT_XORP = 14
|
||||||
|
RTPROT_NTK = 15
|
||||||
|
RTPROT_DHCP = 16
|
||||||
|
RTPROT_MROUTED = 17
|
||||||
|
RTPROT_BABEL = 42
|
||||||
|
RTPROT_BGP = 186
|
||||||
|
RTPROT_ISIS = 187
|
||||||
|
RTPROT_OSPF = 188
|
||||||
|
RTPROT_RIP = 189
|
||||||
|
RTPROT_EIGRP = 192
|
||||||
|
)
|
||||||
|
|
||||||
|
// Route scopes, from uapi/linux/rtnetlink.h.
|
||||||
|
const (
|
||||||
|
RT_SCOPE_UNIVERSE = 0
|
||||||
|
RT_SCOPE_SITE = 200
|
||||||
|
RT_SCOPE_LINK = 253
|
||||||
|
RT_SCOPE_HOST = 254
|
||||||
|
RT_SCOPE_NOWHERE = 255
|
||||||
|
)
|
||||||
|
|
||||||
|
// Route flags, from uapi/linux/rtnetlink.h.
|
||||||
|
const (
|
||||||
|
RTM_F_NOTIFY = 0x100
|
||||||
|
RTM_F_CLONED = 0x200
|
||||||
|
RTM_F_EQUALIZE = 0x400
|
||||||
|
RTM_F_PREFIX = 0x800
|
||||||
|
RTM_F_LOOKUP_TABLE = 0x1000
|
||||||
|
RTM_F_FIB_MATCH = 0x2000
|
||||||
|
)
|
||||||
|
|
||||||
|
// Route tables, from uapi/linux/rtnetlink.h.
|
||||||
|
const (
|
||||||
|
RT_TABLE_UNSPEC = 0
|
||||||
|
RT_TABLE_COMPAT = 252
|
||||||
|
RT_TABLE_DEFAULT = 253
|
||||||
|
RT_TABLE_MAIN = 254
|
||||||
|
RT_TABLE_LOCAL = 255
|
||||||
|
)
|
||||||
|
|
||||||
|
// Route attributes, from uapi/linux/rtnetlink.h.
|
||||||
|
const (
|
||||||
|
RTA_UNSPEC = 0
|
||||||
|
RTA_DST = 1
|
||||||
|
RTA_SRC = 2
|
||||||
|
RTA_IIF = 3
|
||||||
|
RTA_OIF = 4
|
||||||
|
RTA_GATEWAY = 5
|
||||||
|
RTA_PRIORITY = 6
|
||||||
|
RTA_PREFSRC = 7
|
||||||
|
RTA_METRICS = 8
|
||||||
|
RTA_MULTIPATH = 9
|
||||||
|
RTA_PROTOINFO = 10
|
||||||
|
RTA_FLOW = 11
|
||||||
|
RTA_CACHEINFO = 12
|
||||||
|
RTA_SESSION = 13
|
||||||
|
RTA_MP_ALGO = 14
|
||||||
|
RTA_TABLE = 15
|
||||||
|
RTA_MARK = 16
|
||||||
|
RTA_MFC_STATS = 17
|
||||||
|
RTA_VIA = 18
|
||||||
|
RTA_NEWDST = 19
|
||||||
|
RTA_PREF = 20
|
||||||
|
RTA_ENCAP_TYPE = 21
|
||||||
|
RTA_ENCAP = 22
|
||||||
|
RTA_EXPIRES = 23
|
||||||
|
RTA_PAD = 24
|
||||||
|
RTA_UID = 25
|
||||||
|
RTA_TTL_PROPAGATE = 26
|
||||||
|
RTA_IP_PROTO = 27
|
||||||
|
RTA_SPORT = 28
|
||||||
|
RTA_DPORT = 29
|
||||||
|
)
|
||||||
|
|
||||||
|
// Route flags, from include/uapi/linux/route.h.
|
||||||
|
const (
|
||||||
|
RTF_GATEWAY = 0x2
|
||||||
|
RTF_UP = 0x1
|
||||||
|
)
|
||||||
|
|
||||||
|
// RtAttr is the header of optional addition route information, as a netlink
|
||||||
|
// attribute. From include/uapi/linux/rtnetlink.h.
|
||||||
|
//
|
||||||
|
// +marshal
|
||||||
|
type RtAttr struct {
|
||||||
|
Len uint16
|
||||||
|
Type uint16
|
||||||
|
}
|
||||||
|
|
||||||
|
// SizeOfRtAttr is the size of RtAttr.
|
||||||
|
const SizeOfRtAttr = 4
|
||||||
464
pkg/abi/linux/nf_tables.go
Normal file
464
pkg/abi/linux/nf_tables.go
Normal file
|
|
@ -0,0 +1,464 @@
|
||||||
|
// Copyright 2024 The gVisor 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 linux
|
||||||
|
|
||||||
|
// This file contains constants required to support nf_tables.
|
||||||
|
|
||||||
|
const NFT_MAX_HOOKS = NF_INET_NUMHOOKS + 1
|
||||||
|
|
||||||
|
// Name length constants for nf_table structures. These correspond to values in
|
||||||
|
// include/uapi/linux/netfilter/nf_tables.h.
|
||||||
|
const (
|
||||||
|
NFT_NAME_MAXLEN = 256
|
||||||
|
NFT_TABLE_MAXNAMELEN = NFT_NAME_MAXLEN
|
||||||
|
NFT_CHAIN_MAXNAMELEN = NFT_NAME_MAXLEN
|
||||||
|
NFT_SET_MAXNAMELEN = NFT_NAME_MAXLEN
|
||||||
|
NFT_OBJ_MAXNAMELEN = NFT_NAME_MAXLEN
|
||||||
|
NFT_USERDATA_MAXLEN = 256
|
||||||
|
NFT_OSF_MAXGENRELEN = 16
|
||||||
|
)
|
||||||
|
|
||||||
|
// 16-byte Registers that can be used to maintain state for rules.
|
||||||
|
// These correspond to values in include/uapi/linux/netfilter/nf_tables.h.
|
||||||
|
const (
|
||||||
|
NFT_REG_VERDICT = iota
|
||||||
|
NFT_REG_1
|
||||||
|
NFT_REG_2
|
||||||
|
NFT_REG_3
|
||||||
|
NFT_REG_4
|
||||||
|
__NFT_REG_MAX
|
||||||
|
)
|
||||||
|
|
||||||
|
// 4-byte Registers that can be used to maintain state for rules.
|
||||||
|
// Note that these overlap with the 16-byte registers in memory.
|
||||||
|
// These correspond to values in include/uapi/linux/netfilter/nf_tables.h.
|
||||||
|
const (
|
||||||
|
NFT_REG32_00 = 8 + iota
|
||||||
|
NFT_REG32_01
|
||||||
|
NFT_REG32_02
|
||||||
|
NFT_REG32_03
|
||||||
|
NFT_REG32_04
|
||||||
|
NFT_REG32_05
|
||||||
|
NFT_REG32_06
|
||||||
|
NFT_REG32_07
|
||||||
|
NFT_REG32_08
|
||||||
|
NFT_REG32_09
|
||||||
|
NFT_REG32_10
|
||||||
|
NFT_REG32_11
|
||||||
|
NFT_REG32_12
|
||||||
|
NFT_REG32_13
|
||||||
|
NFT_REG32_14
|
||||||
|
NFT_REG32_15
|
||||||
|
)
|
||||||
|
|
||||||
|
// Other register constants, corresponding to values in
|
||||||
|
// include/uapi/linux/netfilter/nf_tables.h.
|
||||||
|
const (
|
||||||
|
NFT_REG_MAX = __NFT_REG_MAX - 1 // Maximum register value
|
||||||
|
NFT_REG_SIZE = 16 // Size of NFT_REG
|
||||||
|
NFT_REG32_SIZE = 4 // Size of NFT_REG32
|
||||||
|
NFT_REG32_COUNT = NFT_REG32_15 - NFT_REG32_00 + 1 // Count of 4-byte registers
|
||||||
|
)
|
||||||
|
|
||||||
|
// Internal nf table verdicts. These are used for ruleset evaluation and
|
||||||
|
// are not returned to userspace.
|
||||||
|
//
|
||||||
|
// These also share their numeric name space with the netfilter verdicts. When
|
||||||
|
// used these values are converted to uint32 (purposefully overflowing the int).
|
||||||
|
// These correspond to values in include/uapi/linux/netfilter/nf_tables.h.
|
||||||
|
const (
|
||||||
|
// Continue evaluation of the current rule.
|
||||||
|
NFT_CONTINUE int32 = -1
|
||||||
|
|
||||||
|
// Terminate evaluation of the current rule.
|
||||||
|
NFT_BREAK int32 = -2
|
||||||
|
|
||||||
|
// Push the current chain on the jump stack and jump to a chain.
|
||||||
|
NFT_JUMP int32 = -3
|
||||||
|
|
||||||
|
// Jump to a chain without pushing the current chain on the jump stack.
|
||||||
|
NFT_GOTO int32 = -4
|
||||||
|
|
||||||
|
// Return to the topmost chain on the jump stack.
|
||||||
|
NFT_RETURN int32 = -5
|
||||||
|
)
|
||||||
|
|
||||||
|
// NfTableMsgType values map to operations within the nftables api.
|
||||||
|
// These correspond to values in include/uapi/linux/netfilter/nf_tables.h.
|
||||||
|
type NfTableMsgType uint16
|
||||||
|
|
||||||
|
// Netlink Netfilter table message types.
|
||||||
|
const (
|
||||||
|
NFT_MSG_NEWTABLE NfTableMsgType = iota
|
||||||
|
NFT_MSG_GETTABLE
|
||||||
|
NFT_MSG_DELTABLE
|
||||||
|
NFT_MSG_NEWCHAIN
|
||||||
|
NFT_MSG_GETCHAIN
|
||||||
|
NFT_MSG_DELCHAIN
|
||||||
|
NFT_MSG_NEWRULE
|
||||||
|
NFT_MSG_GETRULE
|
||||||
|
NFT_MSG_DELRULE
|
||||||
|
NFT_MSG_NEWSET
|
||||||
|
NFT_MSG_GETSET
|
||||||
|
NFT_MSG_DELSET
|
||||||
|
NFT_MSG_NEWSETELEM
|
||||||
|
NFT_MSG_GETSETELEM
|
||||||
|
NFT_MSG_DELSETELEM
|
||||||
|
NFT_MSG_NEWGEN
|
||||||
|
NFT_MSG_GETGEN
|
||||||
|
NFT_MSG_TRACE
|
||||||
|
NFT_MSG_NEWOBJ
|
||||||
|
NFT_MSG_GETOBJ
|
||||||
|
NFT_MSG_DELOBJ
|
||||||
|
NFT_MSG_GETOBJ_RESET
|
||||||
|
NFT_MSG_NEWFLOWTABLE
|
||||||
|
NFT_MSG_GETFLOWTABLE
|
||||||
|
NFT_MSG_DELFLOWTABLE
|
||||||
|
NFT_MSG_GETRULE_RESET
|
||||||
|
NFT_MSG_DESTROYTABLE
|
||||||
|
NFT_MSG_DESTROYCHAIN
|
||||||
|
NFT_MSG_DESTROYRULE
|
||||||
|
NFT_MSG_DESTROYSET
|
||||||
|
NFT_MSG_DESTROYSETELEM
|
||||||
|
NFT_MSG_DESTROYOBJ
|
||||||
|
NFT_MSG_DESTROYFLOWTABLE
|
||||||
|
NFT_MSG_GETSETELEM_RESET
|
||||||
|
NFT_MSG_MAX
|
||||||
|
)
|
||||||
|
|
||||||
|
var nfTableMsgTypeStrings = [...]string{
|
||||||
|
NFT_MSG_NEWTABLE: "NFT_MSG_NEWTABLE",
|
||||||
|
NFT_MSG_GETTABLE: "NFT_MSG_GETTABLE",
|
||||||
|
NFT_MSG_DELTABLE: "NFT_MSG_DELTABLE",
|
||||||
|
NFT_MSG_NEWCHAIN: "NFT_MSG_NEWCHAIN",
|
||||||
|
NFT_MSG_GETCHAIN: "NFT_MSG_GETCHAIN",
|
||||||
|
NFT_MSG_DELCHAIN: "NFT_MSG_DELCHAIN",
|
||||||
|
NFT_MSG_NEWRULE: "NFT_MSG_NEWRULE",
|
||||||
|
NFT_MSG_GETRULE: "NFT_MSG_GETRULE",
|
||||||
|
NFT_MSG_DELRULE: "NFT_MSG_DELRULE",
|
||||||
|
NFT_MSG_NEWSET: "NFT_MSG_NEWSET",
|
||||||
|
NFT_MSG_GETSET: "NFT_MSG_GETSET",
|
||||||
|
NFT_MSG_DELSET: "NFT_MSG_DELSET",
|
||||||
|
NFT_MSG_NEWSETELEM: "NFT_MSG_NEWSETELEM",
|
||||||
|
NFT_MSG_GETSETELEM: "NFT_MSG_GETSETELEM",
|
||||||
|
NFT_MSG_DELSETELEM: "NFT_MSG_DELSETELEM",
|
||||||
|
NFT_MSG_NEWGEN: "NFT_MSG_NEWGEN",
|
||||||
|
NFT_MSG_GETGEN: "NFT_MSG_GETGEN",
|
||||||
|
NFT_MSG_TRACE: "NFT_MSG_TRACE",
|
||||||
|
NFT_MSG_NEWOBJ: "NFT_MSG_NEWOBJ",
|
||||||
|
NFT_MSG_GETOBJ: "NFT_MSG_GETOBJ",
|
||||||
|
NFT_MSG_DELOBJ: "NFT_MSG_DELOBJ",
|
||||||
|
NFT_MSG_GETOBJ_RESET: "NFT_MSG_GETOBJ_RESET",
|
||||||
|
NFT_MSG_NEWFLOWTABLE: "NFT_MSG_NEWFLOWTABLE",
|
||||||
|
NFT_MSG_GETFLOWTABLE: "NFT_MSG_GETFLOWTABLE",
|
||||||
|
NFT_MSG_DELFLOWTABLE: "NFT_MSG_DELFLOWTABLE",
|
||||||
|
NFT_MSG_GETRULE_RESET: "NFT_MSG_GETRULE_RESET",
|
||||||
|
NFT_MSG_DESTROYTABLE: "NFT_MSG_DESTROYTABLE",
|
||||||
|
NFT_MSG_DESTROYCHAIN: "NFT_MSG_DESTROYCHAIN",
|
||||||
|
NFT_MSG_DESTROYRULE: "NFT_MSG_DESTROYRULE",
|
||||||
|
NFT_MSG_DESTROYSET: "NFT_MSG_DESTROYSET",
|
||||||
|
NFT_MSG_DESTROYSETELEM: "NFT_MSG_DESTROYSETELEM",
|
||||||
|
NFT_MSG_DESTROYOBJ: "NFT_MSG_DESTROYOBJ",
|
||||||
|
NFT_MSG_DESTROYFLOWTABLE: "NFT_MSG_DESTROYFLOWTABLE",
|
||||||
|
NFT_MSG_GETSETELEM_RESET: "NFT_MSG_GETSETELEM_RESET",
|
||||||
|
NFT_MSG_MAX: "NFT_MSG_MAX",
|
||||||
|
}
|
||||||
|
|
||||||
|
// String returns the string representation of the NfTableMsgType.
|
||||||
|
func (msg NfTableMsgType) String() string {
|
||||||
|
if int(msg) < len(nfTableMsgTypeStrings) {
|
||||||
|
return nfTableMsgTypeStrings[msg]
|
||||||
|
}
|
||||||
|
return "UNKNOWN"
|
||||||
|
}
|
||||||
|
|
||||||
|
// NfTableListAttributes represents the netfilter attributes for lists of data.
|
||||||
|
// These correspond to values in include/uapi/linux/netfilter/nf_tables.h.
|
||||||
|
const (
|
||||||
|
NFTA_LIST_UNSPEC uint16 = iota
|
||||||
|
NFTA_LIST_ELEM
|
||||||
|
__NFTA_LIST_MAX
|
||||||
|
NFTA_LIST_MAX = __NFTA_LIST_MAX - 1
|
||||||
|
)
|
||||||
|
|
||||||
|
// NfTableHookAttributes represents the netfilter hook attributes.
|
||||||
|
// These correspond to values in include/uapi/linux/netfilter/nf_tables.h.
|
||||||
|
const (
|
||||||
|
NFTA_HOOK_UNSPEC uint16 = iota
|
||||||
|
NFTA_HOOK_HOOKNUM
|
||||||
|
NFTA_HOOK_PRIORITY
|
||||||
|
NFTA_HOOK_DEV
|
||||||
|
NFTA_HOOK_DEVS
|
||||||
|
__NFTA_HOOK_MAX
|
||||||
|
NFTA_HOOK_MAX = __NFTA_HOOK_MAX - 1
|
||||||
|
)
|
||||||
|
|
||||||
|
// NfTableFlags represents table flags that can be set for a table, namely dormant.
|
||||||
|
// These correspond to values in include/uapi/linux/netfilter/nf_tables.h.
|
||||||
|
const (
|
||||||
|
NFT_TABLE_F_DORMANT uint32 = 0x1
|
||||||
|
NFT_TABLE_F_OWNER = 0x2
|
||||||
|
NFT_TABLE_F_PERSIST = 0x4
|
||||||
|
NFT_TABLE_F_MASK = NFT_TABLE_F_DORMANT | NFT_TABLE_F_OWNER | NFT_TABLE_F_PERSIST
|
||||||
|
)
|
||||||
|
|
||||||
|
// NfTableAttributes represents the netfilter table attributes.
|
||||||
|
// These correspond to values in include/uapi/linux/netfilter/nf_tables.h.
|
||||||
|
const (
|
||||||
|
NFTA_TABLE_UNSPEC uint16 = iota
|
||||||
|
NFTA_TABLE_NAME
|
||||||
|
NFTA_TABLE_FLAGS
|
||||||
|
NFTA_TABLE_USE
|
||||||
|
NFTA_TABLE_HANDLE
|
||||||
|
NFTA_TABLE_PAD
|
||||||
|
NFTA_TABLE_USERDATA
|
||||||
|
NFTA_TABLE_OWNER
|
||||||
|
__NFTA_TABLE_MAX
|
||||||
|
)
|
||||||
|
|
||||||
|
// NFTA_TABLE_MAX is the maximum netfilter table attribute.
|
||||||
|
const NFTA_TABLE_MAX = __NFTA_TABLE_MAX - 1
|
||||||
|
|
||||||
|
// NfTableChainFlags represents chain flags that can be set for a chain.
|
||||||
|
// These correspond to values in include/uapi/linux/netfilter/nf_tables.h.
|
||||||
|
const (
|
||||||
|
NFT_CHAIN_BASE uint32 = (1 << 0)
|
||||||
|
NFT_CHAIN_HW_OFFLOAD = (1 << 1)
|
||||||
|
NFT_CHAIN_BINDING = (1 << 2)
|
||||||
|
NFT_CHAIN_FLAGS = (NFT_CHAIN_BASE | NFT_CHAIN_HW_OFFLOAD | NFT_CHAIN_BINDING)
|
||||||
|
)
|
||||||
|
|
||||||
|
// NfTableChainAttributes represents the netfilter chain attributes.
|
||||||
|
// These correspond to values in include/uapi/linux/netfilter/nf_tables.h.
|
||||||
|
const (
|
||||||
|
NFTA_CHAIN_UNSPEC uint16 = iota
|
||||||
|
NFTA_CHAIN_TABLE
|
||||||
|
NFTA_CHAIN_HANDLE
|
||||||
|
NFTA_CHAIN_NAME
|
||||||
|
NFTA_CHAIN_HOOK
|
||||||
|
NFTA_CHAIN_POLICY
|
||||||
|
NFTA_CHAIN_USE
|
||||||
|
NFTA_CHAIN_TYPE
|
||||||
|
NFTA_CHAIN_COUNTERS
|
||||||
|
NFTA_CHAIN_PAD
|
||||||
|
NFTA_CHAIN_FLAGS
|
||||||
|
NFTA_CHAIN_ID
|
||||||
|
NFTA_CHAIN_USERDATA
|
||||||
|
__NFTA_CHAIN_MAX
|
||||||
|
NFTA_CHAIN_MAX = __NFTA_CHAIN_MAX - 1
|
||||||
|
)
|
||||||
|
|
||||||
|
// NfTableRuleAttributes represents the netfilter rule attributes.
|
||||||
|
// These correspond to values in include/uapi/linux/netfilter/nf_tables.h.
|
||||||
|
const (
|
||||||
|
NFTA_RULE_UNSPEC uint16 = iota
|
||||||
|
NFTA_RULE_TABLE
|
||||||
|
NFTA_RULE_CHAIN
|
||||||
|
NFTA_RULE_HANDLE
|
||||||
|
NFTA_RULE_EXPRESSIONS
|
||||||
|
NFTA_RULE_COMPAT
|
||||||
|
NFTA_RULE_POSITION
|
||||||
|
NFTA_RULE_USERDATA
|
||||||
|
NFTA_RULE_PAD
|
||||||
|
NFTA_RULE_ID
|
||||||
|
NFTA_RULE_POSITION_ID
|
||||||
|
NFTA_RULE_CHAIN_ID
|
||||||
|
__NFTA_RULE_MAX
|
||||||
|
NFTA_RULE_MAX = __NFTA_RULE_MAX - 1
|
||||||
|
)
|
||||||
|
|
||||||
|
// NfTableDataTypes represents the netfilter data types.
|
||||||
|
// These correspond to values in include/uapi/linux/netfilter/nf_tables.h.
|
||||||
|
const (
|
||||||
|
NFT_DATA_VALUE = iota
|
||||||
|
NFT_DATA_VERDICT = 0xffffff00
|
||||||
|
)
|
||||||
|
|
||||||
|
// NfTableDataReservedMask represents the netfilter data reserved mask for internally used types.
|
||||||
|
// These correspond to values in include/uapi/linux/netfilter/nf_tables.h.
|
||||||
|
const (
|
||||||
|
NFT_DATA_RESERVED_MASK = 0xffffff00
|
||||||
|
)
|
||||||
|
|
||||||
|
// NfTableDataAttributes represents the netfilter data attributes.
|
||||||
|
// These correspond to values in include/uapi/linux/netfilter/nf_tables.h.
|
||||||
|
const (
|
||||||
|
NFTA_DATA_UNSPEC uint16 = iota
|
||||||
|
NFTA_DATA_VALUE
|
||||||
|
NFTA_DATA_VERDICT
|
||||||
|
__NFTA_DATA_MAX
|
||||||
|
NFTA_DATA_MAX = __NFTA_DATA_MAX - 1
|
||||||
|
)
|
||||||
|
|
||||||
|
// NFT_DATA_VALUE_MAXLEN is the maximum length of a netfilter data value.
|
||||||
|
const NFT_DATA_VALUE_MAXLEN = 64
|
||||||
|
|
||||||
|
// NfTableVerdictAttributes represents the netfilter verdict attributes.
|
||||||
|
// These correspond to values in include/uapi/linux/netfilter/nf_tables.h.
|
||||||
|
const (
|
||||||
|
NFTA_VERDICT_UNSPEC uint16 = iota
|
||||||
|
NFTA_VERDICT_CODE
|
||||||
|
NFTA_VERDICT_CHAIN
|
||||||
|
NFTA_VERDICT_CHAIN_ID
|
||||||
|
__NFTA_VERDICT_MAX
|
||||||
|
NFTA_VERDICT_MAX = __NFTA_VERDICT_MAX - 1
|
||||||
|
)
|
||||||
|
|
||||||
|
// NfTableExprAttributes represents the netfilter expression attributes.
|
||||||
|
// These correspond to values in include/uapi/linux/netfilter/nf_tables.h.
|
||||||
|
const (
|
||||||
|
NFTA_EXPR_UNSPEC uint16 = iota
|
||||||
|
NFTA_EXPR_NAME
|
||||||
|
NFTA_EXPR_DATA
|
||||||
|
__NFTA_EXPR_MAX
|
||||||
|
NFTA_EXPR_MAX = __NFTA_EXPR_MAX - 1
|
||||||
|
)
|
||||||
|
|
||||||
|
// NfTableImmediateAttributes represents the netfilter immediate attributes.
|
||||||
|
// These correspond to values in include/uapi/linux/netfilter/nf_tables.h.
|
||||||
|
const (
|
||||||
|
NFTA_IMMEDIATE_UNSPEC uint16 = iota
|
||||||
|
NFTA_IMMEDIATE_DREG
|
||||||
|
NFTA_IMMEDIATE_DATA
|
||||||
|
__NFTA_IMMEDIATE_MAX
|
||||||
|
NFTA_IMMEDIATE_MAX = __NFTA_IMMEDIATE_MAX - 1
|
||||||
|
)
|
||||||
|
|
||||||
|
// Nf table relational operators.
|
||||||
|
// Used by the nft comparison operation to compare values in registers.
|
||||||
|
// These correspond to enum values in include/uapi/linux/netfilter/nf_tables.h.
|
||||||
|
const (
|
||||||
|
NFT_CMP_EQ = iota // equal
|
||||||
|
NFT_CMP_NEQ // not equal
|
||||||
|
NFT_CMP_LT // less than
|
||||||
|
NFT_CMP_LTE // less than or equal to
|
||||||
|
NFT_CMP_GT // greater than
|
||||||
|
NFT_CMP_GTE // greater than or equal to
|
||||||
|
)
|
||||||
|
|
||||||
|
// Nf table range operators.
|
||||||
|
// Used by the nft range operation to compare values in registers.
|
||||||
|
// These correspond to enum values in include/uapi/linux/netfilter/nf_tables.h.
|
||||||
|
const (
|
||||||
|
NFT_RANGE_EQ = iota
|
||||||
|
NFT_RANGE_NEQ
|
||||||
|
)
|
||||||
|
|
||||||
|
// Nf table payload expression offset bases.
|
||||||
|
// Used by the nft payload operations to access appropriate data in the packet.
|
||||||
|
// These correspond to enum values in include/uapi/linux/netfilter/nf_tables.h.
|
||||||
|
const (
|
||||||
|
NFT_PAYLOAD_LL_HEADER = iota // link layer header
|
||||||
|
NFT_PAYLOAD_NETWORK_HEADER // network header
|
||||||
|
NFT_PAYLOAD_TRANSPORT_HEADER // transport header
|
||||||
|
NFT_PAYLOAD_INNER_HEADER // inner header / payload
|
||||||
|
NFT_PAYLOAD_TUN_HEADER // tunneling protocol header
|
||||||
|
)
|
||||||
|
|
||||||
|
// Nf table payload expression checksum types.
|
||||||
|
// Used by the nft payload set operation to mark the type of checksum to use.
|
||||||
|
// These correspond to enum values in include/uapi/linux/netfilter/nf_tables.h.
|
||||||
|
const (
|
||||||
|
NFT_PAYLOAD_CSUM_NONE = iota // no checksumming
|
||||||
|
NFT_PAYLOAD_CSUM_INET // internet checksum (RFC 791)
|
||||||
|
NFT_PAYLOAD_CSUM_SCTP // CRC-32c, for use in SCTP header (RFC 3309)
|
||||||
|
)
|
||||||
|
|
||||||
|
// Nf table payload expression checksum flags.
|
||||||
|
// Used by the nft payload set operation to mark the flags for checksumming.
|
||||||
|
// These correspond to enum values in include/uapi/linux/netfilter/nf_tables.h.
|
||||||
|
const (
|
||||||
|
NFT_PAYLOAD_L4CSUM_PSEUDOHDR = (1 << 0) // use pseudoheader for L4 checksum
|
||||||
|
)
|
||||||
|
|
||||||
|
// Nf table bitwise operators.
|
||||||
|
// Used by the nft bitwise operation to perform bitwise math over register data.
|
||||||
|
// These correspond to enum values in include/uapi/linux/netfilter/nf_tables.h.
|
||||||
|
const (
|
||||||
|
NFT_BITWISE_BOOL = iota // mask-and-xor operation for NOT, AND, OR, & XOR
|
||||||
|
NFT_BITWISE_LSHIFT // left-shift operation
|
||||||
|
NFT_BITWISE_RSHIFT // right-shift operation
|
||||||
|
)
|
||||||
|
|
||||||
|
// Nf table route expression keys.
|
||||||
|
// Used by the nft route operation to determine the routing data to retrieve.
|
||||||
|
// These correspond to enum values in include/uapi/linux/netfilter/nf_tables.h.
|
||||||
|
const (
|
||||||
|
// Traffic Class Identifier (Realm) associated with route
|
||||||
|
NFT_RT_CLASSID = iota
|
||||||
|
|
||||||
|
// Routing nexthop for IPv4 (next IPv4 address to jump to)
|
||||||
|
NFT_RT_NEXTHOP4
|
||||||
|
|
||||||
|
// Routing nexthop for IPv6 (next IPv6 address to jump to)
|
||||||
|
NFT_RT_NEXTHOP6
|
||||||
|
|
||||||
|
// Maximum Segment Size for TCP connections (largest size for a single packet)
|
||||||
|
NFT_RT_TCPMSS
|
||||||
|
|
||||||
|
// Bool for whether packet route involves a IPsec transform st xfrm is applied
|
||||||
|
NFT_RT_XFRM
|
||||||
|
)
|
||||||
|
|
||||||
|
// Nf table byteorder operators.
|
||||||
|
// Used by the nft byteorder operation to convert data in a register to a
|
||||||
|
// specific byte order.
|
||||||
|
// These correspond to enum values in include/uapi/linux/netfilter/nf_tables.h.
|
||||||
|
const (
|
||||||
|
NFT_BYTEORDER_NTOH = iota // network to host operator
|
||||||
|
NFT_BYTEORDER_HTON // host to network operator
|
||||||
|
)
|
||||||
|
|
||||||
|
// Nf tables meta expression keys.
|
||||||
|
// Used by the nft meta operation to retrieve meta data from the packet.
|
||||||
|
// These correspond to enum values in include/uapi/linux/netfilter/nf_tables.h.
|
||||||
|
const (
|
||||||
|
NFT_META_LEN = iota // Packet length
|
||||||
|
NFT_META_PROTOCOL // Packet ethertype protocol, invalid in OUTPUT
|
||||||
|
NFT_META_PRIORITY // Packet priority
|
||||||
|
NFT_META_MARK // Packet mark
|
||||||
|
NFT_META_IIF // Packet input interface index
|
||||||
|
NFT_META_OIF // Packet output interface index
|
||||||
|
NFT_META_IIFNAME // Packet input interface name
|
||||||
|
NFT_META_OIFNAME // Packet output interface name
|
||||||
|
NFT_META_IIFTYPE // Packet input interface type
|
||||||
|
NFT_META_OIFTYPE // Packet output interface type
|
||||||
|
NFT_META_SKUID // Originating socket UID
|
||||||
|
NFT_META_SKGID // Originating socket GID
|
||||||
|
NFT_META_NFTRACE // Packet nftrace bit
|
||||||
|
NFT_META_RTCLASSID // Realm value of packet's route
|
||||||
|
NFT_META_SECMARK // Packet secmark
|
||||||
|
NFT_META_NFPROTO // Netfilter protocol
|
||||||
|
NFT_META_L4PROTO // Layer 4 protocol number
|
||||||
|
NFT_META_BRI_IIFNAME // Packet input bridge interface name
|
||||||
|
NFT_META_BRI_OIFNAME // Packet output bridge interface name
|
||||||
|
NFT_META_PKTTYPE // Packet type, special handling for loopback
|
||||||
|
NFT_META_CPU // CPU id through smp_processor_id()
|
||||||
|
NFT_META_IIFGROUP // Packet input interface group
|
||||||
|
NFT_META_OIFGROUP // Packet output interface group
|
||||||
|
NFT_META_CGROUP // Socket control group
|
||||||
|
NFT_META_PRANDOM // A 32bit pseudo-random number
|
||||||
|
NFT_META_SECPATH // Boolean, secpath_exists
|
||||||
|
NFT_META_IIFKIND // Packet input interface kind name
|
||||||
|
NFT_META_OIFKIND // Packet output interface kind name
|
||||||
|
NFT_META_BRI_IIFPVID // Packet input bridge port pvid
|
||||||
|
NFT_META_BRI_IIFVPROTO // Packet input bridge vlan proto
|
||||||
|
NFT_META_TIME_NS // Time since epoch (in nanoseconds)
|
||||||
|
NFT_META_TIME_DAY // Day of week (from 0 = Sunday to 6 = Saturday)
|
||||||
|
NFT_META_TIME_HOUR // Hour of day (in sec), secs since start of day
|
||||||
|
NFT_META_SDIF // Slave device interface index
|
||||||
|
NFT_META_SDIFNAME // Slave device interface name
|
||||||
|
NFT_META_BRI_BROUTE // Packet br_netfilter_broute bit
|
||||||
|
)
|
||||||
44
pkg/abi/linux/poll.go
Normal file
44
pkg/abi/linux/poll.go
Normal file
|
|
@ -0,0 +1,44 @@
|
||||||
|
// Copyright 2018 The gVisor 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 linux
|
||||||
|
|
||||||
|
// PollFD is struct pollfd, used by poll(2)/ppoll(2), from uapi/asm-generic/poll.h.
|
||||||
|
//
|
||||||
|
// +marshal slice:PollFDSlice
|
||||||
|
type PollFD struct {
|
||||||
|
FD int32
|
||||||
|
Events int16
|
||||||
|
REvents int16
|
||||||
|
}
|
||||||
|
|
||||||
|
// Poll event flags, used by poll(2)/ppoll(2) and/or
|
||||||
|
// epoll_ctl(2)/epoll_wait(2), from uapi/asm-generic/poll.h.
|
||||||
|
const (
|
||||||
|
POLLIN = 0x0001
|
||||||
|
POLLPRI = 0x0002
|
||||||
|
POLLOUT = 0x0004
|
||||||
|
POLLERR = 0x0008
|
||||||
|
POLLHUP = 0x0010
|
||||||
|
POLLNVAL = 0x0020
|
||||||
|
POLLRDNORM = 0x0040
|
||||||
|
POLLRDBAND = 0x0080
|
||||||
|
POLLWRNORM = 0x0100
|
||||||
|
POLLWRBAND = 0x0200
|
||||||
|
POLLMSG = 0x0400
|
||||||
|
POLLREMOVE = 0x1000
|
||||||
|
POLLRDHUP = 0x2000
|
||||||
|
POLLFREE = 0x4000
|
||||||
|
POLL_BUSY_LOOP = 0x8000
|
||||||
|
)
|
||||||
179
pkg/abi/linux/prctl.go
Normal file
179
pkg/abi/linux/prctl.go
Normal file
|
|
@ -0,0 +1,179 @@
|
||||||
|
// Copyright 2018 The gVisor 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 linux
|
||||||
|
|
||||||
|
// PR_* flags, from <linux/pcrtl.h> for prctl(2).
|
||||||
|
const (
|
||||||
|
// PR_SET_PDEATHSIG sets the process' death signal.
|
||||||
|
PR_SET_PDEATHSIG = 1
|
||||||
|
|
||||||
|
// PR_GET_PDEATHSIG gets the process' death signal.
|
||||||
|
PR_GET_PDEATHSIG = 2
|
||||||
|
|
||||||
|
// PR_GET_DUMPABLE gets the process' dumpable flag.
|
||||||
|
PR_GET_DUMPABLE = 3
|
||||||
|
|
||||||
|
// PR_SET_DUMPABLE sets the process' dumpable flag.
|
||||||
|
PR_SET_DUMPABLE = 4
|
||||||
|
|
||||||
|
// PR_GET_KEEPCAPS gets the value of the keep capabilities flag.
|
||||||
|
PR_GET_KEEPCAPS = 7
|
||||||
|
|
||||||
|
// PR_SET_KEEPCAPS sets the value of the keep capabilities flag.
|
||||||
|
PR_SET_KEEPCAPS = 8
|
||||||
|
|
||||||
|
// PR_GET_TIMING gets the process' timing method.
|
||||||
|
PR_GET_TIMING = 13
|
||||||
|
|
||||||
|
// PR_SET_TIMING sets the process' timing method.
|
||||||
|
PR_SET_TIMING = 14
|
||||||
|
|
||||||
|
// PR_SET_NAME sets the process' name.
|
||||||
|
PR_SET_NAME = 15
|
||||||
|
|
||||||
|
// PR_GET_NAME gets the process' name.
|
||||||
|
PR_GET_NAME = 16
|
||||||
|
|
||||||
|
// PR_GET_SECCOMP gets a process' seccomp mode.
|
||||||
|
PR_GET_SECCOMP = 21
|
||||||
|
|
||||||
|
// PR_SET_SECCOMP sets a process' seccomp mode.
|
||||||
|
PR_SET_SECCOMP = 22
|
||||||
|
|
||||||
|
// PR_CAPBSET_READ gets the capability bounding set.
|
||||||
|
PR_CAPBSET_READ = 23
|
||||||
|
|
||||||
|
// PR_CAPBSET_DROP sets the capability bounding set.
|
||||||
|
PR_CAPBSET_DROP = 24
|
||||||
|
|
||||||
|
// PR_GET_TSC gets the value of the flag determining whether the
|
||||||
|
// timestamp counter can be read.
|
||||||
|
PR_GET_TSC = 25
|
||||||
|
|
||||||
|
// PR_SET_TSC sets the value of the flag determining whether the
|
||||||
|
// timestamp counter can be read.
|
||||||
|
PR_SET_TSC = 26
|
||||||
|
|
||||||
|
// PR_SET_TIMERSLACK sets the process' time slack.
|
||||||
|
PR_SET_TIMERSLACK = 29
|
||||||
|
|
||||||
|
// PR_GET_TIMERSLACK gets the process' time slack.
|
||||||
|
PR_GET_TIMERSLACK = 30
|
||||||
|
|
||||||
|
// PR_TASK_PERF_EVENTS_DISABLE disables all performance counters
|
||||||
|
// attached to the calling process.
|
||||||
|
PR_TASK_PERF_EVENTS_DISABLE = 31
|
||||||
|
|
||||||
|
// PR_TASK_PERF_EVENTS_ENABLE enables all performance counters attached
|
||||||
|
// to the calling process.
|
||||||
|
PR_TASK_PERF_EVENTS_ENABLE = 32
|
||||||
|
|
||||||
|
// PR_MCE_KILL sets the machine check memory corruption kill policy for
|
||||||
|
// the calling thread.
|
||||||
|
PR_MCE_KILL = 33
|
||||||
|
|
||||||
|
// PR_MCE_KILL_GET gets the machine check memory corruption kill policy
|
||||||
|
// for the calling thread.
|
||||||
|
PR_MCE_KILL_GET = 34
|
||||||
|
|
||||||
|
// PR_SET_MM modifies certain kernel memory map descriptor fields of
|
||||||
|
// the calling process. See prctl(2) for more information.
|
||||||
|
PR_SET_MM = 35
|
||||||
|
|
||||||
|
PR_SET_MM_START_CODE = 1
|
||||||
|
PR_SET_MM_END_CODE = 2
|
||||||
|
PR_SET_MM_START_DATA = 3
|
||||||
|
PR_SET_MM_END_DATA = 4
|
||||||
|
PR_SET_MM_START_STACK = 5
|
||||||
|
PR_SET_MM_START_BRK = 6
|
||||||
|
PR_SET_MM_BRK = 7
|
||||||
|
PR_SET_MM_ARG_START = 8
|
||||||
|
PR_SET_MM_ARG_END = 9
|
||||||
|
PR_SET_MM_ENV_START = 10
|
||||||
|
PR_SET_MM_ENV_END = 11
|
||||||
|
PR_SET_MM_AUXV = 12
|
||||||
|
// PR_SET_MM_EXE_FILE supersedes the /proc/pid/exe symbolic link with a
|
||||||
|
// new one pointing to a new executable file identified by the file
|
||||||
|
// descriptor provided in arg3 argument. See prctl(2) for more
|
||||||
|
// information.
|
||||||
|
PR_SET_MM_EXE_FILE = 13
|
||||||
|
PR_SET_MM_MAP = 14
|
||||||
|
PR_SET_MM_MAP_SIZE = 15
|
||||||
|
|
||||||
|
// PR_SET_CHILD_SUBREAPER sets the "child subreaper" attribute of the
|
||||||
|
// calling process.
|
||||||
|
PR_SET_CHILD_SUBREAPER = 36
|
||||||
|
|
||||||
|
// PR_GET_CHILD_SUBREAPER gets the "child subreaper" attribute of the
|
||||||
|
// calling process.
|
||||||
|
PR_GET_CHILD_SUBREAPER = 37
|
||||||
|
|
||||||
|
// PR_SET_NO_NEW_PRIVS sets the calling thread's no_new_privs bit.
|
||||||
|
PR_SET_NO_NEW_PRIVS = 38
|
||||||
|
|
||||||
|
// PR_GET_NO_NEW_PRIVS gets the calling thread's no_new_privs bit.
|
||||||
|
PR_GET_NO_NEW_PRIVS = 39
|
||||||
|
|
||||||
|
// PR_GET_TID_ADDRESS retrieves the clear_child_tid address.
|
||||||
|
PR_GET_TID_ADDRESS = 40
|
||||||
|
|
||||||
|
// PR_SET_THP_DISABLE sets the state of the "THP disable" flag for the
|
||||||
|
// calling thread.
|
||||||
|
PR_SET_THP_DISABLE = 41
|
||||||
|
|
||||||
|
// PR_GET_THP_DISABLE gets the state of the "THP disable" flag for the
|
||||||
|
// calling thread.
|
||||||
|
PR_GET_THP_DISABLE = 42
|
||||||
|
|
||||||
|
// PR_MPX_ENABLE_MANAGEMENT enables kernel management of Memory
|
||||||
|
// Protection eXtensions (MPX) bounds tables.
|
||||||
|
PR_MPX_ENABLE_MANAGEMENT = 43
|
||||||
|
|
||||||
|
// PR_MPX_DISABLE_MANAGEMENT disables kernel management of Memory
|
||||||
|
// Protection eXtensions (MPX) bounds tables.
|
||||||
|
PR_MPX_DISABLE_MANAGEMENT = 44
|
||||||
|
|
||||||
|
// The following constants are used to control thread scheduling on cores.
|
||||||
|
PR_SCHED_CORE_SCOPE_THREAD = 0
|
||||||
|
PR_SCHED_CORE_SCOPE_THREAD_GROUP = 1
|
||||||
|
|
||||||
|
// PR_SET_VMA sets VMA attributes.
|
||||||
|
PR_SET_VMA = 0x53564d41
|
||||||
|
PR_SET_VMA_ANON_NAME = 0
|
||||||
|
// From kernel/sys.c:
|
||||||
|
ANON_VMA_NAME_MAX_LEN = 80
|
||||||
|
|
||||||
|
// PR_SET_PTRACER allows a specific process (or any, if PR_SET_PTRACER_ANY is
|
||||||
|
// specified) to ptrace the current task.
|
||||||
|
PR_SET_PTRACER = 0x59616d61
|
||||||
|
PR_SET_PTRACER_ANY = -1
|
||||||
|
)
|
||||||
|
|
||||||
|
// From <asm/prctl.h>
|
||||||
|
// Flags are used in syscall arch_prctl(2).
|
||||||
|
const (
|
||||||
|
ARCH_SET_GS = 0x1001
|
||||||
|
ARCH_SET_FS = 0x1002
|
||||||
|
ARCH_GET_FS = 0x1003
|
||||||
|
ARCH_GET_GS = 0x1004
|
||||||
|
ARCH_SET_CPUID = 0x1012
|
||||||
|
)
|
||||||
|
|
||||||
|
// Flags for prctl(PR_SET_DUMPABLE), defined in include/linux/sched/coredump.h.
|
||||||
|
const (
|
||||||
|
SUID_DUMP_DISABLE = 0
|
||||||
|
SUID_DUMP_USER = 1
|
||||||
|
SUID_DUMP_ROOT = 2
|
||||||
|
)
|
||||||
95
pkg/abi/linux/ptrace.go
Normal file
95
pkg/abi/linux/ptrace.go
Normal file
|
|
@ -0,0 +1,95 @@
|
||||||
|
// Copyright 2018 The gVisor 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 linux
|
||||||
|
|
||||||
|
// ptrace commands from include/uapi/linux/ptrace.h.
|
||||||
|
const (
|
||||||
|
PTRACE_TRACEME = 0
|
||||||
|
PTRACE_PEEKTEXT = 1
|
||||||
|
PTRACE_PEEKDATA = 2
|
||||||
|
PTRACE_PEEKUSR = 3
|
||||||
|
PTRACE_POKETEXT = 4
|
||||||
|
PTRACE_POKEDATA = 5
|
||||||
|
PTRACE_POKEUSR = 6
|
||||||
|
PTRACE_CONT = 7
|
||||||
|
PTRACE_KILL = 8
|
||||||
|
PTRACE_SINGLESTEP = 9
|
||||||
|
PTRACE_ATTACH = 16
|
||||||
|
PTRACE_DETACH = 17
|
||||||
|
PTRACE_SYSCALL = 24
|
||||||
|
PTRACE_SETOPTIONS = 0x4200
|
||||||
|
PTRACE_GETEVENTMSG = 0x4201
|
||||||
|
PTRACE_GETSIGINFO = 0x4202
|
||||||
|
PTRACE_SETSIGINFO = 0x4203
|
||||||
|
PTRACE_GETREGSET = 0x4204
|
||||||
|
PTRACE_SETREGSET = 0x4205
|
||||||
|
PTRACE_SEIZE = 0x4206
|
||||||
|
PTRACE_INTERRUPT = 0x4207
|
||||||
|
PTRACE_LISTEN = 0x4208
|
||||||
|
PTRACE_PEEKSIGINFO = 0x4209
|
||||||
|
PTRACE_GETSIGMASK = 0x420a
|
||||||
|
PTRACE_SETSIGMASK = 0x420b
|
||||||
|
PTRACE_SECCOMP_GET_FILTER = 0x420c
|
||||||
|
PTRACE_SECCOMP_GET_METADATA = 0x420d
|
||||||
|
)
|
||||||
|
|
||||||
|
// ptrace commands from arch/x86/include/uapi/asm/ptrace-abi.h.
|
||||||
|
const (
|
||||||
|
PTRACE_GETREGS = 12
|
||||||
|
PTRACE_SETREGS = 13
|
||||||
|
PTRACE_GETFPREGS = 14
|
||||||
|
PTRACE_SETFPREGS = 15
|
||||||
|
PTRACE_GETFPXREGS = 18
|
||||||
|
PTRACE_SETFPXREGS = 19
|
||||||
|
PTRACE_OLDSETOPTIONS = 21
|
||||||
|
PTRACE_GET_THREAD_AREA = 25
|
||||||
|
PTRACE_SET_THREAD_AREA = 26
|
||||||
|
PTRACE_ARCH_PRCTL = 30
|
||||||
|
PTRACE_SYSEMU = 31
|
||||||
|
PTRACE_SYSEMU_SINGLESTEP = 32
|
||||||
|
PTRACE_SINGLEBLOCK = 33
|
||||||
|
)
|
||||||
|
|
||||||
|
// ptrace event codes from include/uapi/linux/ptrace.h.
|
||||||
|
const (
|
||||||
|
PTRACE_EVENT_FORK = 1
|
||||||
|
PTRACE_EVENT_VFORK = 2
|
||||||
|
PTRACE_EVENT_CLONE = 3
|
||||||
|
PTRACE_EVENT_EXEC = 4
|
||||||
|
PTRACE_EVENT_VFORK_DONE = 5
|
||||||
|
PTRACE_EVENT_EXIT = 6
|
||||||
|
PTRACE_EVENT_SECCOMP = 7
|
||||||
|
PTRACE_EVENT_STOP = 128
|
||||||
|
)
|
||||||
|
|
||||||
|
// PTRACE_SETOPTIONS options from include/uapi/linux/ptrace.h.
|
||||||
|
const (
|
||||||
|
PTRACE_O_TRACESYSGOOD = 1
|
||||||
|
PTRACE_O_TRACEFORK = 1 << PTRACE_EVENT_FORK
|
||||||
|
PTRACE_O_TRACEVFORK = 1 << PTRACE_EVENT_VFORK
|
||||||
|
PTRACE_O_TRACECLONE = 1 << PTRACE_EVENT_CLONE
|
||||||
|
PTRACE_O_TRACEEXEC = 1 << PTRACE_EVENT_EXEC
|
||||||
|
PTRACE_O_TRACEVFORKDONE = 1 << PTRACE_EVENT_VFORK_DONE
|
||||||
|
PTRACE_O_TRACEEXIT = 1 << PTRACE_EVENT_EXIT
|
||||||
|
PTRACE_O_TRACESECCOMP = 1 << PTRACE_EVENT_SECCOMP
|
||||||
|
PTRACE_O_EXITKILL = 1 << 20
|
||||||
|
PTRACE_O_SUSPEND_SECCOMP = 1 << 21
|
||||||
|
)
|
||||||
|
|
||||||
|
// YAMA ptrace_scope levels from security/yama/yama_lsm.c.
|
||||||
|
const (
|
||||||
|
YAMA_SCOPE_DISABLED = 0
|
||||||
|
YAMA_SCOPE_RELATIONAL = 1
|
||||||
|
)
|
||||||
69
pkg/abi/linux/ptrace_amd64.go
Normal file
69
pkg/abi/linux/ptrace_amd64.go
Normal file
|
|
@ -0,0 +1,69 @@
|
||||||
|
// Copyright 2020 The gVisor 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.
|
||||||
|
|
||||||
|
//go:build amd64
|
||||||
|
// +build amd64
|
||||||
|
|
||||||
|
package linux
|
||||||
|
|
||||||
|
// PtraceRegs is the set of CPU registers exposed by ptrace. Source:
|
||||||
|
// syscall.PtraceRegs.
|
||||||
|
//
|
||||||
|
// +marshal
|
||||||
|
// +stateify savable
|
||||||
|
type PtraceRegs struct {
|
||||||
|
R15 uint64
|
||||||
|
R14 uint64
|
||||||
|
R13 uint64
|
||||||
|
R12 uint64
|
||||||
|
Rbp uint64
|
||||||
|
Rbx uint64
|
||||||
|
R11 uint64
|
||||||
|
R10 uint64
|
||||||
|
R9 uint64
|
||||||
|
R8 uint64
|
||||||
|
Rax uint64
|
||||||
|
Rcx uint64
|
||||||
|
Rdx uint64
|
||||||
|
Rsi uint64
|
||||||
|
Rdi uint64
|
||||||
|
Orig_rax uint64
|
||||||
|
Rip uint64
|
||||||
|
Cs uint64
|
||||||
|
Eflags uint64
|
||||||
|
Rsp uint64
|
||||||
|
Ss uint64
|
||||||
|
Fs_base uint64
|
||||||
|
Gs_base uint64
|
||||||
|
Ds uint64
|
||||||
|
Es uint64
|
||||||
|
Fs uint64
|
||||||
|
Gs uint64
|
||||||
|
}
|
||||||
|
|
||||||
|
// InstructionPointer returns the address of the next instruction to
|
||||||
|
// be executed.
|
||||||
|
func (p *PtraceRegs) InstructionPointer() uint64 {
|
||||||
|
return p.Rip
|
||||||
|
}
|
||||||
|
|
||||||
|
// StackPointer returns the address of the Stack pointer.
|
||||||
|
func (p *PtraceRegs) StackPointer() uint64 {
|
||||||
|
return p.Rsp
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetStackPointer sets the stack pointer to the specified value.
|
||||||
|
func (p *PtraceRegs) SetStackPointer(sp uint64) {
|
||||||
|
p.Rsp = sp
|
||||||
|
}
|
||||||
77
pkg/abi/linux/ptrace_arm64.go
Normal file
77
pkg/abi/linux/ptrace_arm64.go
Normal file
|
|
@ -0,0 +1,77 @@
|
||||||
|
// Copyright 2019 The gVisor 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.
|
||||||
|
|
||||||
|
//go:build arm64
|
||||||
|
// +build arm64
|
||||||
|
|
||||||
|
package linux
|
||||||
|
|
||||||
|
const (
|
||||||
|
// PSR bits
|
||||||
|
PSR_MODE_EL0t = 0x00000000
|
||||||
|
PSR_MODE_EL1t = 0x00000004
|
||||||
|
PSR_MODE_EL1h = 0x00000005
|
||||||
|
PSR_MODE_EL2t = 0x00000008
|
||||||
|
PSR_MODE_EL2h = 0x00000009
|
||||||
|
PSR_MODE_EL3t = 0x0000000c
|
||||||
|
PSR_MODE_EL3h = 0x0000000d
|
||||||
|
PSR_MODE_MASK = 0x0000000f
|
||||||
|
|
||||||
|
// AArch32 CPSR bits
|
||||||
|
PSR_MODE32_BIT = 0x00000010
|
||||||
|
|
||||||
|
// AArch64 SPSR bits
|
||||||
|
PSR_F_BIT = 0x00000040
|
||||||
|
PSR_I_BIT = 0x00000080
|
||||||
|
PSR_A_BIT = 0x00000100
|
||||||
|
PSR_D_BIT = 0x00000200
|
||||||
|
PSR_BTYPE_MASK = 0x00000c00
|
||||||
|
PSR_SSBS_BIT = 0x00001000
|
||||||
|
PSR_PAN_BIT = 0x00400000
|
||||||
|
PSR_UAO_BIT = 0x00800000
|
||||||
|
PSR_DIT_BIT = 0x01000000
|
||||||
|
PSR_TCO_BIT = 0x02000000
|
||||||
|
PSR_V_BIT = 0x10000000
|
||||||
|
PSR_C_BIT = 0x20000000
|
||||||
|
PSR_Z_BIT = 0x40000000
|
||||||
|
PSR_N_BIT = 0x80000000
|
||||||
|
)
|
||||||
|
|
||||||
|
// PtraceRegs is the set of CPU registers exposed by ptrace. Source:
|
||||||
|
// syscall.PtraceRegs.
|
||||||
|
//
|
||||||
|
// +marshal
|
||||||
|
// +stateify savable
|
||||||
|
type PtraceRegs struct {
|
||||||
|
Regs [31]uint64
|
||||||
|
Sp uint64
|
||||||
|
Pc uint64
|
||||||
|
Pstate uint64
|
||||||
|
}
|
||||||
|
|
||||||
|
// InstructionPointer returns the address of the next instruction to be
|
||||||
|
// executed.
|
||||||
|
func (p *PtraceRegs) InstructionPointer() uint64 {
|
||||||
|
return p.Pc
|
||||||
|
}
|
||||||
|
|
||||||
|
// StackPointer returns the address of the Stack pointer.
|
||||||
|
func (p *PtraceRegs) StackPointer() uint64 {
|
||||||
|
return p.Sp
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetStackPointer sets the stack pointer to the specified value.
|
||||||
|
func (p *PtraceRegs) SetStackPointer(sp uint64) {
|
||||||
|
p.Sp = sp
|
||||||
|
}
|
||||||
130
pkg/abi/linux/rseq.go
Normal file
130
pkg/abi/linux/rseq.go
Normal file
|
|
@ -0,0 +1,130 @@
|
||||||
|
// Copyright 2019 The gVisor 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 linux
|
||||||
|
|
||||||
|
// Flags passed to rseq(2).
|
||||||
|
//
|
||||||
|
// Defined in include/uapi/linux/rseq.h.
|
||||||
|
const (
|
||||||
|
// RSEQ_FLAG_UNREGISTER unregisters the current thread.
|
||||||
|
RSEQ_FLAG_UNREGISTER = 1 << 0
|
||||||
|
)
|
||||||
|
|
||||||
|
// Critical section flags used in RSeqCriticalSection.Flags and RSeq.Flags.
|
||||||
|
//
|
||||||
|
// Defined in include/uapi/linux/rseq.h.
|
||||||
|
const (
|
||||||
|
// RSEQ_CS_FLAG_NO_RESTART_ON_PREEMPT inhibits restart on preemption.
|
||||||
|
RSEQ_CS_FLAG_NO_RESTART_ON_PREEMPT = 1 << 0
|
||||||
|
|
||||||
|
// RSEQ_CS_FLAG_NO_RESTART_ON_SIGNAL inhibits restart on signal
|
||||||
|
// delivery.
|
||||||
|
RSEQ_CS_FLAG_NO_RESTART_ON_SIGNAL = 1 << 1
|
||||||
|
|
||||||
|
// RSEQ_CS_FLAG_NO_RESTART_ON_MIGRATE inhibits restart on CPU
|
||||||
|
// migration.
|
||||||
|
RSEQ_CS_FLAG_NO_RESTART_ON_MIGRATE = 1 << 2
|
||||||
|
)
|
||||||
|
|
||||||
|
// RSeqCriticalSection describes a restartable sequences critical section. It
|
||||||
|
// is equivalent to struct rseq_cs, defined in include/uapi/linux/rseq.h.
|
||||||
|
//
|
||||||
|
// In userspace, this structure is always aligned to 32 bytes.
|
||||||
|
//
|
||||||
|
// +marshal
|
||||||
|
type RSeqCriticalSection struct {
|
||||||
|
// Version is the version of this structure. Version 0 is defined here.
|
||||||
|
Version uint32
|
||||||
|
|
||||||
|
// Flags are the critical section flags, defined above.
|
||||||
|
Flags uint32
|
||||||
|
|
||||||
|
// Start is the start address of the critical section.
|
||||||
|
Start uint64
|
||||||
|
|
||||||
|
// PostCommitOffset is the offset from Start of the first instruction
|
||||||
|
// outside of the critical section.
|
||||||
|
PostCommitOffset uint64
|
||||||
|
|
||||||
|
// Abort is the abort address. It must be outside the critical section,
|
||||||
|
// and the 4 bytes prior must match the abort signature.
|
||||||
|
Abort uint64
|
||||||
|
}
|
||||||
|
|
||||||
|
const (
|
||||||
|
// SizeOfRSeqCriticalSection is the size of RSeqCriticalSection.
|
||||||
|
SizeOfRSeqCriticalSection = 32
|
||||||
|
|
||||||
|
// SizeOfRSeqSignature is the size of the signature immediately
|
||||||
|
// preceding RSeqCriticalSection.Abort.
|
||||||
|
SizeOfRSeqSignature = 4
|
||||||
|
)
|
||||||
|
|
||||||
|
// Special values for RSeq.CPUID, defined in include/uapi/linux/rseq.h.
|
||||||
|
const (
|
||||||
|
// RSEQ_CPU_ID_UNINITIALIZED indicates that this thread has not
|
||||||
|
// performed rseq initialization.
|
||||||
|
RSEQ_CPU_ID_UNINITIALIZED = ^uint32(0) // -1
|
||||||
|
|
||||||
|
// RSEQ_CPU_ID_REGISTRATION_FAILED indicates that rseq initialization
|
||||||
|
// failed.
|
||||||
|
RSEQ_CPU_ID_REGISTRATION_FAILED = ^uint32(1) // -2
|
||||||
|
)
|
||||||
|
|
||||||
|
// RSeq is the thread-local restartable sequences config/status. It
|
||||||
|
// is equivalent to struct rseq, defined in include/uapi/linux/rseq.h.
|
||||||
|
//
|
||||||
|
// In userspace, this structure is always aligned to 32 bytes.
|
||||||
|
type RSeq struct {
|
||||||
|
// CPUIDStart contains the current CPU ID if rseq is initialized.
|
||||||
|
//
|
||||||
|
// This field should only be read by the thread which registered this
|
||||||
|
// structure, and must be read atomically.
|
||||||
|
CPUIDStart uint32
|
||||||
|
|
||||||
|
// CPUID contains the current CPU ID or one of the CPU ID special
|
||||||
|
// values defined above.
|
||||||
|
//
|
||||||
|
// This field should only be read by the thread which registered this
|
||||||
|
// structure, and must be read atomically.
|
||||||
|
CPUID uint32
|
||||||
|
|
||||||
|
// RSeqCriticalSection is a pointer to the current RSeqCriticalSection
|
||||||
|
// block, or NULL. It is reset to NULL by the kernel on restart or
|
||||||
|
// non-restarting preempt/signal.
|
||||||
|
//
|
||||||
|
// This field should only be written by the thread which registered
|
||||||
|
// this structure, and must be written atomically.
|
||||||
|
RSeqCriticalSection uint64
|
||||||
|
|
||||||
|
// Flags are the critical section flags that apply to all critical
|
||||||
|
// sections on this thread, defined above.
|
||||||
|
Flags uint32
|
||||||
|
}
|
||||||
|
|
||||||
|
const (
|
||||||
|
// SizeOfRSeq is the size of RSeq.
|
||||||
|
//
|
||||||
|
// Note that RSeq is naively 24 bytes. However, it has 32-byte
|
||||||
|
// alignment, which in C increases sizeof to 32. That is the size that
|
||||||
|
// the Linux kernel uses.
|
||||||
|
SizeOfRSeq = 32
|
||||||
|
|
||||||
|
// AlignOfRSeq is the standard alignment of RSeq.
|
||||||
|
AlignOfRSeq = 32
|
||||||
|
|
||||||
|
// OffsetOfRSeqCriticalSection is the offset of RSeqCriticalSection in RSeq.
|
||||||
|
OffsetOfRSeqCriticalSection = 8
|
||||||
|
)
|
||||||
48
pkg/abi/linux/rusage.go
Normal file
48
pkg/abi/linux/rusage.go
Normal file
|
|
@ -0,0 +1,48 @@
|
||||||
|
// Copyright 2018 The gVisor 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 linux
|
||||||
|
|
||||||
|
// Flags that may be used with wait4(2) and getrusage(2).
|
||||||
|
const (
|
||||||
|
// wait4(2) uses this to aggregate RUSAGE_SELF and RUSAGE_CHILDREN.
|
||||||
|
RUSAGE_BOTH = -0x2
|
||||||
|
|
||||||
|
// getrusage(2) flags.
|
||||||
|
RUSAGE_CHILDREN = -0x1
|
||||||
|
RUSAGE_SELF = 0x0
|
||||||
|
RUSAGE_THREAD = 0x1
|
||||||
|
)
|
||||||
|
|
||||||
|
// Rusage represents the Linux struct rusage.
|
||||||
|
//
|
||||||
|
// +marshal
|
||||||
|
type Rusage struct {
|
||||||
|
UTime Timeval
|
||||||
|
STime Timeval
|
||||||
|
MaxRSS int64
|
||||||
|
IXRSS int64
|
||||||
|
IDRSS int64
|
||||||
|
ISRSS int64
|
||||||
|
MinFlt int64
|
||||||
|
MajFlt int64
|
||||||
|
NSwap int64
|
||||||
|
InBlock int64
|
||||||
|
OuBlock int64
|
||||||
|
MsgSnd int64
|
||||||
|
MsgRcv int64
|
||||||
|
NSignals int64
|
||||||
|
NVCSw int64
|
||||||
|
NIvCSw int64
|
||||||
|
}
|
||||||
37
pkg/abi/linux/sched.go
Normal file
37
pkg/abi/linux/sched.go
Normal file
|
|
@ -0,0 +1,37 @@
|
||||||
|
// Copyright 2018 The gVisor 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 linux
|
||||||
|
|
||||||
|
// Scheduling policies, exposed by sched_getscheduler(2)/sched_setscheduler(2).
|
||||||
|
const (
|
||||||
|
SCHED_NORMAL = 0
|
||||||
|
SCHED_FIFO = 1
|
||||||
|
SCHED_RR = 2
|
||||||
|
SCHED_BATCH = 3
|
||||||
|
SCHED_IDLE = 5
|
||||||
|
SCHED_DEADLINE = 6
|
||||||
|
SCHED_MICROQ = 16
|
||||||
|
|
||||||
|
// SCHED_RESET_ON_FORK is a flag that indicates that the process is
|
||||||
|
// reverted back to SCHED_NORMAL on fork.
|
||||||
|
SCHED_RESET_ON_FORK = 0x40000000
|
||||||
|
)
|
||||||
|
|
||||||
|
// Scheduling priority group selectors.
|
||||||
|
const (
|
||||||
|
PRIO_PGRP = 0x1
|
||||||
|
PRIO_PROCESS = 0x0
|
||||||
|
PRIO_USER = 0x2
|
||||||
|
)
|
||||||
173
pkg/abi/linux/seccomp.go
Normal file
173
pkg/abi/linux/seccomp.go
Normal file
|
|
@ -0,0 +1,173 @@
|
||||||
|
// Copyright 2018 The gVisor 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 linux
|
||||||
|
|
||||||
|
import "fmt"
|
||||||
|
|
||||||
|
// Seccomp constants taken from <linux/seccomp.h>.
|
||||||
|
const (
|
||||||
|
SECCOMP_MODE_NONE = 0
|
||||||
|
SECCOMP_MODE_FILTER = 2
|
||||||
|
|
||||||
|
SECCOMP_RET_ACTION_FULL = 0xffff0000
|
||||||
|
SECCOMP_RET_ACTION = 0x7fff0000
|
||||||
|
SECCOMP_RET_DATA = 0x0000ffff
|
||||||
|
|
||||||
|
SECCOMP_SET_MODE_FILTER = 1
|
||||||
|
SECCOMP_GET_ACTION_AVAIL = 2
|
||||||
|
SECCOMP_GET_NOTIF_SIZES = 3
|
||||||
|
|
||||||
|
SECCOMP_FILTER_FLAG_TSYNC = 1
|
||||||
|
SECCOMP_FILTER_FLAG_NEW_LISTENER = 1 << 3
|
||||||
|
|
||||||
|
SECCOMP_USER_NOTIF_FLAG_CONTINUE = 1
|
||||||
|
|
||||||
|
SECCOMP_IOCTL_NOTIF_RECV = 0xc0502100
|
||||||
|
SECCOMP_IOCTL_NOTIF_SEND = 0xc0182101
|
||||||
|
SECCOMP_IOCTL_NOTIF_SET_FLAGS = 0x40082104
|
||||||
|
|
||||||
|
SECCOMP_USER_NOTIF_FD_SYNC_WAKE_UP = 1
|
||||||
|
)
|
||||||
|
|
||||||
|
// BPFAction is an action for a BPF filter.
|
||||||
|
type BPFAction uint32
|
||||||
|
|
||||||
|
// BPFAction definitions.
|
||||||
|
const (
|
||||||
|
SECCOMP_RET_KILL_PROCESS BPFAction = 0x80000000
|
||||||
|
SECCOMP_RET_KILL_THREAD BPFAction = 0x00000000
|
||||||
|
SECCOMP_RET_TRAP BPFAction = 0x00030000
|
||||||
|
SECCOMP_RET_ERRNO BPFAction = 0x00050000
|
||||||
|
SECCOMP_RET_TRACE BPFAction = 0x7ff00000
|
||||||
|
SECCOMP_RET_USER_NOTIF BPFAction = 0x7fc00000
|
||||||
|
SECCOMP_RET_ALLOW BPFAction = 0x7fff0000
|
||||||
|
)
|
||||||
|
|
||||||
|
func (a BPFAction) String() string {
|
||||||
|
switch a & SECCOMP_RET_ACTION_FULL {
|
||||||
|
case SECCOMP_RET_KILL_PROCESS:
|
||||||
|
return "kill process"
|
||||||
|
case SECCOMP_RET_KILL_THREAD:
|
||||||
|
return "kill thread"
|
||||||
|
case SECCOMP_RET_TRAP:
|
||||||
|
data := a.Data()
|
||||||
|
if data == 0 {
|
||||||
|
return "trap"
|
||||||
|
}
|
||||||
|
return fmt.Sprintf("trap (data=%#x)", data)
|
||||||
|
case SECCOMP_RET_ERRNO:
|
||||||
|
return fmt.Sprintf("return errno=%#x", a.Data())
|
||||||
|
case SECCOMP_RET_TRACE:
|
||||||
|
data := a.Data()
|
||||||
|
if data == 0 {
|
||||||
|
return "trace"
|
||||||
|
}
|
||||||
|
return fmt.Sprintf("trace (data=%#x)", data)
|
||||||
|
case SECCOMP_RET_ALLOW:
|
||||||
|
return "allow"
|
||||||
|
case SECCOMP_RET_USER_NOTIF:
|
||||||
|
return "unotify"
|
||||||
|
}
|
||||||
|
return fmt.Sprintf("invalid action: %#x", uint32(a))
|
||||||
|
}
|
||||||
|
|
||||||
|
// Data returns the SECCOMP_RET_DATA portion of the action.
|
||||||
|
func (a BPFAction) Data() uint16 {
|
||||||
|
return uint16(a & SECCOMP_RET_DATA)
|
||||||
|
}
|
||||||
|
|
||||||
|
// WithReturnCode sets the lower 16 bits of the SECCOMP_RET_ERRNO or
|
||||||
|
// SECCOMP_RET_TRACE actions to the provided return code, overwriting the previous
|
||||||
|
// action, and returns a new BPFAction. If not SECCOMP_RET_ERRNO or
|
||||||
|
// SECCOMP_RET_TRACE then this panics.
|
||||||
|
func (a BPFAction) WithReturnCode(code uint16) BPFAction {
|
||||||
|
// mask out the previous return value
|
||||||
|
baseAction := a & SECCOMP_RET_ACTION_FULL
|
||||||
|
if baseAction == SECCOMP_RET_ERRNO || baseAction == SECCOMP_RET_TRACE {
|
||||||
|
return BPFAction(uint32(baseAction) | uint32(code))
|
||||||
|
}
|
||||||
|
panic("WithReturnCode only valid for SECCOMP_RET_ERRNO and SECCOMP_RET_TRACE")
|
||||||
|
}
|
||||||
|
|
||||||
|
// SockFprog is sock_fprog taken from <linux/filter.h>.
|
||||||
|
type SockFprog struct {
|
||||||
|
Len uint16
|
||||||
|
pad [6]byte
|
||||||
|
Filter *BPFInstruction
|
||||||
|
}
|
||||||
|
|
||||||
|
// SeccompData is equivalent to struct seccomp_data, which contains the data
|
||||||
|
// passed to seccomp-bpf filters.
|
||||||
|
//
|
||||||
|
// +marshal
|
||||||
|
type SeccompData struct {
|
||||||
|
// Nr is the system call number.
|
||||||
|
Nr int32
|
||||||
|
|
||||||
|
// Arch is an AUDIT_ARCH_* value indicating the system call convention.
|
||||||
|
Arch uint32
|
||||||
|
|
||||||
|
// InstructionPointer is the value of the instruction pointer at the time
|
||||||
|
// of the system call.
|
||||||
|
InstructionPointer uint64
|
||||||
|
|
||||||
|
// Args contains the first 6 system call arguments.
|
||||||
|
Args [6]uint64
|
||||||
|
}
|
||||||
|
|
||||||
|
// SeccompNotifResp is equivalent to struct seccomp_notif_resp.
|
||||||
|
//
|
||||||
|
// +marshal
|
||||||
|
type SeccompNotifResp struct {
|
||||||
|
ID uint64
|
||||||
|
Val int64
|
||||||
|
Error int32
|
||||||
|
Flags uint32
|
||||||
|
}
|
||||||
|
|
||||||
|
// SeccompNotifSizes is equivalent to struct seccomp_notif_sizes.
|
||||||
|
//
|
||||||
|
// +marshal
|
||||||
|
type SeccompNotifSizes struct {
|
||||||
|
Notif uint16
|
||||||
|
Notif_resp uint16
|
||||||
|
Data uint16
|
||||||
|
}
|
||||||
|
|
||||||
|
// SeccompNotif is equivalent to struct seccomp_notif.
|
||||||
|
//
|
||||||
|
// +marshal
|
||||||
|
type SeccompNotif struct {
|
||||||
|
ID uint64
|
||||||
|
Pid int32
|
||||||
|
Flags uint32
|
||||||
|
Data SeccompData
|
||||||
|
}
|
||||||
|
|
||||||
|
// String returns a human-friendly representation of this `SeccompData`.
|
||||||
|
func (sd SeccompData) String() string {
|
||||||
|
return fmt.Sprintf(
|
||||||
|
"sysno=%d arch=%#x rip=%#x args=[%#x %#x %#x %#x %#x %#x]",
|
||||||
|
sd.Nr,
|
||||||
|
sd.Arch,
|
||||||
|
sd.InstructionPointer,
|
||||||
|
sd.Args[0],
|
||||||
|
sd.Args[1],
|
||||||
|
sd.Args[2],
|
||||||
|
sd.Args[3],
|
||||||
|
sd.Args[4],
|
||||||
|
sd.Args[5],
|
||||||
|
)
|
||||||
|
}
|
||||||
82
pkg/abi/linux/sem.go
Normal file
82
pkg/abi/linux/sem.go
Normal file
|
|
@ -0,0 +1,82 @@
|
||||||
|
// Copyright 2018 The gVisor 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 linux
|
||||||
|
|
||||||
|
// semctl Command Definitions. Source: include/uapi/linux/sem.h
|
||||||
|
const (
|
||||||
|
GETPID = 11
|
||||||
|
GETVAL = 12
|
||||||
|
GETALL = 13
|
||||||
|
GETNCNT = 14
|
||||||
|
GETZCNT = 15
|
||||||
|
SETVAL = 16
|
||||||
|
SETALL = 17
|
||||||
|
)
|
||||||
|
|
||||||
|
// ipcs ctl cmds. Source: include/uapi/linux/sem.h
|
||||||
|
const (
|
||||||
|
SEM_STAT = 18
|
||||||
|
SEM_INFO = 19
|
||||||
|
SEM_STAT_ANY = 20
|
||||||
|
)
|
||||||
|
|
||||||
|
// Information about system-wide semaphore limits and parameters.
|
||||||
|
//
|
||||||
|
// Source: include/uapi/linux/sem.h
|
||||||
|
const (
|
||||||
|
SEMMNI = 32000
|
||||||
|
SEMMSL = 32000
|
||||||
|
SEMMNS = SEMMNI * SEMMSL
|
||||||
|
SEMOPM = 500
|
||||||
|
SEMVMX = 32767
|
||||||
|
SEMAEM = SEMVMX
|
||||||
|
|
||||||
|
SEMUME = SEMOPM
|
||||||
|
SEMMNU = SEMMNS
|
||||||
|
SEMMAP = SEMMNS
|
||||||
|
SEMUSZ = 20
|
||||||
|
)
|
||||||
|
|
||||||
|
// Semaphore flags.
|
||||||
|
const (
|
||||||
|
SEM_UNDO = 0x1000
|
||||||
|
)
|
||||||
|
|
||||||
|
// Sembuf is equivalent to struct sembuf.
|
||||||
|
//
|
||||||
|
// +marshal slice:SembufSlice
|
||||||
|
type Sembuf struct {
|
||||||
|
SemNum uint16
|
||||||
|
SemOp int16
|
||||||
|
SemFlg int16
|
||||||
|
}
|
||||||
|
|
||||||
|
// SemInfo is equivalent to struct seminfo.
|
||||||
|
//
|
||||||
|
// Source: include/uapi/linux/sem.h
|
||||||
|
//
|
||||||
|
// +marshal
|
||||||
|
type SemInfo struct {
|
||||||
|
SemMap uint32
|
||||||
|
SemMni uint32
|
||||||
|
SemMns uint32
|
||||||
|
SemMnu uint32
|
||||||
|
SemMsl uint32
|
||||||
|
SemOpm uint32
|
||||||
|
SemUme uint32
|
||||||
|
SemUsz uint32
|
||||||
|
SemVmx uint32
|
||||||
|
SemAem uint32
|
||||||
|
}
|
||||||
34
pkg/abi/linux/sem_amd64.go
Normal file
34
pkg/abi/linux/sem_amd64.go
Normal file
|
|
@ -0,0 +1,34 @@
|
||||||
|
// Copyright 2020 The gVisor 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.
|
||||||
|
|
||||||
|
//go:build amd64
|
||||||
|
// +build amd64
|
||||||
|
|
||||||
|
package linux
|
||||||
|
|
||||||
|
// SemidDS is equivalent to struct semid64_ds.
|
||||||
|
//
|
||||||
|
// Source: arch/x86/include/uapi/asm/sembuf.h
|
||||||
|
//
|
||||||
|
// +marshal
|
||||||
|
type SemidDS struct {
|
||||||
|
SemPerm IPCPerm
|
||||||
|
SemOTime TimeT
|
||||||
|
unused1 uint64
|
||||||
|
SemCTime TimeT
|
||||||
|
unused2 uint64
|
||||||
|
SemNSems uint64
|
||||||
|
unused3 uint64
|
||||||
|
unused4 uint64
|
||||||
|
}
|
||||||
32
pkg/abi/linux/sem_arm64.go
Normal file
32
pkg/abi/linux/sem_arm64.go
Normal file
|
|
@ -0,0 +1,32 @@
|
||||||
|
// Copyright 2020 The gVisor 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.
|
||||||
|
|
||||||
|
//go:build arm64
|
||||||
|
// +build arm64
|
||||||
|
|
||||||
|
package linux
|
||||||
|
|
||||||
|
// SemidDS is equivalent to struct semid64_ds.
|
||||||
|
//
|
||||||
|
// Source: include/uapi/asm-generic/sembuf.h
|
||||||
|
//
|
||||||
|
// +marshal
|
||||||
|
type SemidDS struct {
|
||||||
|
SemPerm IPCPerm
|
||||||
|
SemOTime TimeT
|
||||||
|
SemCTime TimeT
|
||||||
|
SemNSems uint64
|
||||||
|
unused3 uint64
|
||||||
|
unused4 uint64
|
||||||
|
}
|
||||||
92
pkg/abi/linux/shm.go
Normal file
92
pkg/abi/linux/shm.go
Normal file
|
|
@ -0,0 +1,92 @@
|
||||||
|
// Copyright 2018 The gVisor 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 linux
|
||||||
|
|
||||||
|
import "math"
|
||||||
|
|
||||||
|
// shmat(2) flags. Source: include/uapi/linux/shm.h
|
||||||
|
const (
|
||||||
|
SHM_RDONLY = 0o10000 // Read-only access.
|
||||||
|
SHM_RND = 0o20000 // Round attach address to SHMLBA boundary.
|
||||||
|
SHM_REMAP = 0o40000 // Take-over region on attach.
|
||||||
|
SHM_EXEC = 0o100000 // Execution access.
|
||||||
|
)
|
||||||
|
|
||||||
|
// IPCPerm.Mode upper byte flags. Source: include/linux/shm.h
|
||||||
|
const (
|
||||||
|
SHM_DEST = 0o1000 // Segment will be destroyed on last detach.
|
||||||
|
SHM_LOCKED = 0o2000 // Segment will not be swapped.
|
||||||
|
SHM_HUGETLB = 0o4000 // Segment will use huge TLB pages.
|
||||||
|
SHM_NORESERVE = 0o10000 // Don't check for reservations.
|
||||||
|
)
|
||||||
|
|
||||||
|
// Additional Linux-only flags for shmctl(2). Source: include/uapi/linux/shm.h
|
||||||
|
const (
|
||||||
|
SHM_LOCK = 11
|
||||||
|
SHM_UNLOCK = 12
|
||||||
|
SHM_STAT = 13
|
||||||
|
SHM_INFO = 14
|
||||||
|
)
|
||||||
|
|
||||||
|
// SHM defaults as specified by linux. Source: include/uapi/linux/shm.h
|
||||||
|
const (
|
||||||
|
SHMMIN = 1
|
||||||
|
SHMMNI = 4096
|
||||||
|
SHMMAX = math.MaxUint64 - 1<<24
|
||||||
|
SHMALL = math.MaxUint64 - 1<<24
|
||||||
|
SHMSEG = 4096
|
||||||
|
)
|
||||||
|
|
||||||
|
// ShmidDS is equivalent to struct shmid64_ds. Source:
|
||||||
|
// include/uapi/asm-generic/shmbuf.h
|
||||||
|
//
|
||||||
|
// +marshal
|
||||||
|
type ShmidDS struct {
|
||||||
|
ShmPerm IPCPerm
|
||||||
|
ShmSegsz uint64
|
||||||
|
ShmAtime TimeT
|
||||||
|
ShmDtime TimeT
|
||||||
|
ShmCtime TimeT
|
||||||
|
ShmCpid int32
|
||||||
|
ShmLpid int32
|
||||||
|
ShmNattach uint64
|
||||||
|
|
||||||
|
Unused4 uint64
|
||||||
|
Unused5 uint64
|
||||||
|
}
|
||||||
|
|
||||||
|
// ShmParams is equivalent to struct shminfo. Source: include/uapi/linux/shm.h
|
||||||
|
//
|
||||||
|
// +marshal
|
||||||
|
type ShmParams struct {
|
||||||
|
ShmMax uint64
|
||||||
|
ShmMin uint64
|
||||||
|
ShmMni uint64
|
||||||
|
ShmSeg uint64
|
||||||
|
ShmAll uint64
|
||||||
|
}
|
||||||
|
|
||||||
|
// ShmInfo is equivalent to struct shm_info. Source: include/uapi/linux/shm.h
|
||||||
|
//
|
||||||
|
// +marshal
|
||||||
|
type ShmInfo struct {
|
||||||
|
UsedIDs int32 // Number of currently existing segments.
|
||||||
|
_ [4]byte
|
||||||
|
ShmTot uint64 // Total number of shared memory pages.
|
||||||
|
ShmRss uint64 // Number of resident shared memory pages.
|
||||||
|
ShmSwp uint64 // Number of swapped shared memory pages.
|
||||||
|
SwapAttempts uint64 // Unused since Linux 2.4.
|
||||||
|
SwapSuccesses uint64 // Unused since Linux 2.4.
|
||||||
|
}
|
||||||
552
pkg/abi/linux/signal.go
Normal file
552
pkg/abi/linux/signal.go
Normal file
|
|
@ -0,0 +1,552 @@
|
||||||
|
// Copyright 2018 The gVisor 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 linux
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/sagernet/gvisor/pkg/bits"
|
||||||
|
"github.com/sagernet/gvisor/pkg/hostarch"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
// SignalMaximum is the highest valid signal number.
|
||||||
|
SignalMaximum = 64
|
||||||
|
|
||||||
|
// FirstStdSignal is the lowest standard signal number.
|
||||||
|
FirstStdSignal = 1
|
||||||
|
|
||||||
|
// LastStdSignal is the highest standard signal number.
|
||||||
|
LastStdSignal = 31
|
||||||
|
|
||||||
|
// FirstRTSignal is the lowest real-time signal number.
|
||||||
|
//
|
||||||
|
// 32 (SIGCANCEL) and 33 (SIGSETXID) are used internally by glibc.
|
||||||
|
FirstRTSignal = 32
|
||||||
|
|
||||||
|
// LastRTSignal is the highest real-time signal number.
|
||||||
|
LastRTSignal = 64
|
||||||
|
|
||||||
|
// NumStdSignals is the number of standard signals.
|
||||||
|
NumStdSignals = LastStdSignal - FirstStdSignal + 1
|
||||||
|
|
||||||
|
// NumRTSignals is the number of realtime signals.
|
||||||
|
NumRTSignals = LastRTSignal - FirstRTSignal + 1
|
||||||
|
)
|
||||||
|
|
||||||
|
// Signal is a signal number.
|
||||||
|
type Signal int
|
||||||
|
|
||||||
|
// IsValid returns true if s is a valid standard or realtime signal. (0 is not
|
||||||
|
// considered valid; interfaces special-casing signal number 0 should check for
|
||||||
|
// 0 first before asserting validity.)
|
||||||
|
func (s Signal) IsValid() bool {
|
||||||
|
return s > 0 && s <= SignalMaximum
|
||||||
|
}
|
||||||
|
|
||||||
|
// IsStandard returns true if s is a standard signal.
|
||||||
|
//
|
||||||
|
// Preconditions: s.IsValid().
|
||||||
|
func (s Signal) IsStandard() bool {
|
||||||
|
return s <= LastStdSignal
|
||||||
|
}
|
||||||
|
|
||||||
|
// IsRealtime returns true if s is a realtime signal.
|
||||||
|
//
|
||||||
|
// Preconditions: s.IsValid().
|
||||||
|
func (s Signal) IsRealtime() bool {
|
||||||
|
return s >= FirstRTSignal
|
||||||
|
}
|
||||||
|
|
||||||
|
// Index returns the index for signal s into arrays of both standard and
|
||||||
|
// realtime signals (e.g. signal masks).
|
||||||
|
//
|
||||||
|
// Preconditions: s.IsValid().
|
||||||
|
func (s Signal) Index() int {
|
||||||
|
return int(s - 1)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Signals.
|
||||||
|
const (
|
||||||
|
SIGABRT = Signal(6)
|
||||||
|
SIGALRM = Signal(14)
|
||||||
|
SIGBUS = Signal(7)
|
||||||
|
SIGCHLD = Signal(17)
|
||||||
|
SIGCLD = Signal(17)
|
||||||
|
SIGCONT = Signal(18)
|
||||||
|
SIGFPE = Signal(8)
|
||||||
|
SIGHUP = Signal(1)
|
||||||
|
SIGILL = Signal(4)
|
||||||
|
SIGINT = Signal(2)
|
||||||
|
SIGIO = Signal(29)
|
||||||
|
SIGIOT = Signal(6)
|
||||||
|
SIGKILL = Signal(9)
|
||||||
|
SIGPIPE = Signal(13)
|
||||||
|
SIGPOLL = Signal(29)
|
||||||
|
SIGPROF = Signal(27)
|
||||||
|
SIGPWR = Signal(30)
|
||||||
|
SIGQUIT = Signal(3)
|
||||||
|
SIGSEGV = Signal(11)
|
||||||
|
SIGSTKFLT = Signal(16)
|
||||||
|
SIGSTOP = Signal(19)
|
||||||
|
SIGSYS = Signal(31)
|
||||||
|
SIGTERM = Signal(15)
|
||||||
|
SIGTRAP = Signal(5)
|
||||||
|
SIGTSTP = Signal(20)
|
||||||
|
SIGTTIN = Signal(21)
|
||||||
|
SIGTTOU = Signal(22)
|
||||||
|
SIGUNUSED = Signal(31)
|
||||||
|
SIGURG = Signal(23)
|
||||||
|
SIGUSR1 = Signal(10)
|
||||||
|
SIGUSR2 = Signal(12)
|
||||||
|
SIGVTALRM = Signal(26)
|
||||||
|
SIGWINCH = Signal(28)
|
||||||
|
SIGXCPU = Signal(24)
|
||||||
|
SIGXFSZ = Signal(25)
|
||||||
|
)
|
||||||
|
|
||||||
|
// SignalSet is a signal mask with a bit corresponding to each signal.
|
||||||
|
//
|
||||||
|
// +marshal
|
||||||
|
type SignalSet uint64
|
||||||
|
|
||||||
|
// SignalSetSize is the size in bytes of a SignalSet.
|
||||||
|
const SignalSetSize = 8
|
||||||
|
|
||||||
|
// MakeSignalSet returns SignalSet with the bit corresponding to each of the
|
||||||
|
// given signals set.
|
||||||
|
func MakeSignalSet(sigs ...Signal) SignalSet {
|
||||||
|
indices := make([]int, len(sigs))
|
||||||
|
for i, sig := range sigs {
|
||||||
|
indices[i] = sig.Index()
|
||||||
|
}
|
||||||
|
return SignalSet(bits.Mask64(indices...))
|
||||||
|
}
|
||||||
|
|
||||||
|
// SignalSetOf returns a SignalSet with a single signal set.
|
||||||
|
func SignalSetOf(sig Signal) SignalSet {
|
||||||
|
return SignalSet(bits.MaskOf64(sig.Index()))
|
||||||
|
}
|
||||||
|
|
||||||
|
// ForEachSignal invokes f for each signal set in the given mask.
|
||||||
|
func ForEachSignal(mask SignalSet, f func(sig Signal)) {
|
||||||
|
bits.ForEachSetBit64(uint64(mask), func(i int) {
|
||||||
|
f(Signal(i + 1))
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 'how' values for rt_sigprocmask(2).
|
||||||
|
const (
|
||||||
|
// SIG_BLOCK blocks the signals in the set.
|
||||||
|
SIG_BLOCK = 0
|
||||||
|
|
||||||
|
// SIG_UNBLOCK blocks the signals in the set.
|
||||||
|
SIG_UNBLOCK = 1
|
||||||
|
|
||||||
|
// SIG_SETMASK sets the signal mask to set.
|
||||||
|
SIG_SETMASK = 2
|
||||||
|
)
|
||||||
|
|
||||||
|
// Signal actions for rt_sigaction(2), from uapi/asm-generic/signal-defs.h.
|
||||||
|
const (
|
||||||
|
// SIG_DFL performs the default action.
|
||||||
|
SIG_DFL = 0
|
||||||
|
|
||||||
|
// SIG_IGN ignores the signal.
|
||||||
|
SIG_IGN = 1
|
||||||
|
)
|
||||||
|
|
||||||
|
// Signal action flags for rt_sigaction(2), from uapi/asm-generic/signal.h.
|
||||||
|
const (
|
||||||
|
SA_NOCLDSTOP = 0x00000001
|
||||||
|
SA_NOCLDWAIT = 0x00000002
|
||||||
|
SA_SIGINFO = 0x00000004
|
||||||
|
SA_RESTORER = 0x04000000
|
||||||
|
SA_ONSTACK = 0x08000000
|
||||||
|
SA_RESTART = 0x10000000
|
||||||
|
SA_NODEFER = 0x40000000
|
||||||
|
SA_RESETHAND = 0x80000000
|
||||||
|
SA_NOMASK = SA_NODEFER
|
||||||
|
SA_ONESHOT = SA_RESETHAND
|
||||||
|
)
|
||||||
|
|
||||||
|
// Signal stack flags for signalstack(2), from include/uapi/linux/signal.h.
|
||||||
|
const (
|
||||||
|
SS_ONSTACK = 1
|
||||||
|
SS_DISABLE = 2
|
||||||
|
)
|
||||||
|
|
||||||
|
// SIGPOLL si_codes.
|
||||||
|
const (
|
||||||
|
// SI_POLL is defined as __SI_POLL in Linux 2.6.
|
||||||
|
SI_POLL = 2 << 16
|
||||||
|
|
||||||
|
// POLL_IN indicates that data input available.
|
||||||
|
POLL_IN = SI_POLL | 1
|
||||||
|
|
||||||
|
// POLL_OUT indicates that output buffers available.
|
||||||
|
POLL_OUT = SI_POLL | 2
|
||||||
|
|
||||||
|
// POLL_MSG indicates that an input message available.
|
||||||
|
POLL_MSG = SI_POLL | 3
|
||||||
|
|
||||||
|
// POLL_ERR indicates that there was an i/o error.
|
||||||
|
POLL_ERR = SI_POLL | 4
|
||||||
|
|
||||||
|
// POLL_PRI indicates that a high priority input available.
|
||||||
|
POLL_PRI = SI_POLL | 5
|
||||||
|
|
||||||
|
// POLL_HUP indicates that a device disconnected.
|
||||||
|
POLL_HUP = SI_POLL | 6
|
||||||
|
)
|
||||||
|
|
||||||
|
// Possible values for si_code.
|
||||||
|
const (
|
||||||
|
// SI_USER is sent by kill, sigsend, raise.
|
||||||
|
SI_USER = 0
|
||||||
|
|
||||||
|
// SI_KERNEL is sent by the kernel from somewhere.
|
||||||
|
SI_KERNEL = 0x80
|
||||||
|
|
||||||
|
// SI_QUEUE is sent by sigqueue.
|
||||||
|
SI_QUEUE = -1
|
||||||
|
|
||||||
|
// SI_TIMER is sent by timer expiration.
|
||||||
|
SI_TIMER = -2
|
||||||
|
|
||||||
|
// SI_MESGQ is sent by real time mesq state change.
|
||||||
|
SI_MESGQ = -3
|
||||||
|
|
||||||
|
// SI_ASYNCIO is sent by AIO completion.
|
||||||
|
SI_ASYNCIO = -4
|
||||||
|
|
||||||
|
// SI_SIGIO is sent by queued SIGIO.
|
||||||
|
SI_SIGIO = -5
|
||||||
|
|
||||||
|
// SI_TKILL is sent by tkill system call.
|
||||||
|
SI_TKILL = -6
|
||||||
|
|
||||||
|
// SI_DETHREAD is sent by execve() killing subsidiary threads.
|
||||||
|
SI_DETHREAD = -7
|
||||||
|
|
||||||
|
// SI_ASYNCNL is sent by glibc async name lookup completion.
|
||||||
|
SI_ASYNCNL = -60
|
||||||
|
)
|
||||||
|
|
||||||
|
// CLD_* codes are only meaningful for SIGCHLD.
|
||||||
|
const (
|
||||||
|
// CLD_EXITED indicates that a task exited.
|
||||||
|
CLD_EXITED = 1
|
||||||
|
|
||||||
|
// CLD_KILLED indicates that a task was killed by a signal.
|
||||||
|
CLD_KILLED = 2
|
||||||
|
|
||||||
|
// CLD_DUMPED indicates that a task was killed by a signal and then dumped
|
||||||
|
// core.
|
||||||
|
CLD_DUMPED = 3
|
||||||
|
|
||||||
|
// CLD_TRAPPED indicates that a task was stopped by ptrace.
|
||||||
|
CLD_TRAPPED = 4
|
||||||
|
|
||||||
|
// CLD_STOPPED indicates that a thread group completed a group stop.
|
||||||
|
CLD_STOPPED = 5
|
||||||
|
|
||||||
|
// CLD_CONTINUED indicates that a group-stopped thread group was continued.
|
||||||
|
CLD_CONTINUED = 6
|
||||||
|
)
|
||||||
|
|
||||||
|
// SYS_* codes are only meaningful for SIGSYS.
|
||||||
|
const (
|
||||||
|
// SYS_SECCOMP indicates that a signal originates from seccomp.
|
||||||
|
SYS_SECCOMP = 1
|
||||||
|
)
|
||||||
|
|
||||||
|
// Possible values for Sigevent.Notify, aka struct sigevent::sigev_notify.
|
||||||
|
const (
|
||||||
|
SIGEV_SIGNAL = 0
|
||||||
|
SIGEV_NONE = 1
|
||||||
|
SIGEV_THREAD = 2
|
||||||
|
SIGEV_THREAD_ID = 4
|
||||||
|
)
|
||||||
|
|
||||||
|
// SIGTRAP si_codes
|
||||||
|
const (
|
||||||
|
TRAP_BRKPT = 1
|
||||||
|
TRAP_TRACE = 2
|
||||||
|
TRAP_BRANCH = 3
|
||||||
|
TRAP_HWBKPT = 4
|
||||||
|
)
|
||||||
|
|
||||||
|
// Sigevent represents struct sigevent.
|
||||||
|
//
|
||||||
|
// +marshal
|
||||||
|
type Sigevent struct {
|
||||||
|
Value uint64 // union sigval {int, void*}
|
||||||
|
Signo int32
|
||||||
|
Notify int32
|
||||||
|
|
||||||
|
// struct sigevent here contains 48-byte union _sigev_un. However, only
|
||||||
|
// member _tid is significant to the kernel.
|
||||||
|
Tid int32
|
||||||
|
UnRemainder [44]byte
|
||||||
|
}
|
||||||
|
|
||||||
|
// SigAction represents struct sigaction.
|
||||||
|
//
|
||||||
|
// +marshal
|
||||||
|
// +stateify savable
|
||||||
|
type SigAction struct {
|
||||||
|
Handler uint64
|
||||||
|
Flags uint64
|
||||||
|
Restorer uint64
|
||||||
|
Mask SignalSet
|
||||||
|
}
|
||||||
|
|
||||||
|
// SignalStack represents information about a user stack, and is equivalent to
|
||||||
|
// stack_t.
|
||||||
|
//
|
||||||
|
// +marshal
|
||||||
|
// +stateify savable
|
||||||
|
type SignalStack struct {
|
||||||
|
Addr uint64
|
||||||
|
Flags uint32
|
||||||
|
_ uint32
|
||||||
|
Size uint64
|
||||||
|
}
|
||||||
|
|
||||||
|
// Contains checks if the stack pointer is within this stack.
|
||||||
|
func (s *SignalStack) Contains(sp hostarch.Addr) bool {
|
||||||
|
return hostarch.Addr(s.Addr) < sp && sp <= hostarch.Addr(s.Addr+s.Size)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Top returns the stack's top address.
|
||||||
|
func (s *SignalStack) Top() hostarch.Addr {
|
||||||
|
return hostarch.Addr(s.Addr + s.Size)
|
||||||
|
}
|
||||||
|
|
||||||
|
// IsEnabled returns true iff this signal stack is marked as enabled.
|
||||||
|
func (s *SignalStack) IsEnabled() bool {
|
||||||
|
return s.Flags&SS_DISABLE == 0
|
||||||
|
}
|
||||||
|
|
||||||
|
// SignalInfo represents information about a signal being delivered, and is
|
||||||
|
// equivalent to struct siginfo in linux kernel(linux/include/uapi/asm-generic/siginfo.h).
|
||||||
|
//
|
||||||
|
// +marshal
|
||||||
|
// +stateify savable
|
||||||
|
type SignalInfo struct {
|
||||||
|
Signo int32 // Signal number
|
||||||
|
Errno int32 // Errno value
|
||||||
|
Code int32 // Signal code
|
||||||
|
_ uint32
|
||||||
|
|
||||||
|
// struct siginfo::_sifields is a union. In SignalInfo, fields in the union
|
||||||
|
// are accessed through methods.
|
||||||
|
//
|
||||||
|
// For reference, here is the definition of _sifields: (_sigfault._trapno,
|
||||||
|
// which does not exist on x86, omitted for clarity)
|
||||||
|
//
|
||||||
|
// union {
|
||||||
|
// int _pad[SI_PAD_SIZE];
|
||||||
|
//
|
||||||
|
// /* kill() */
|
||||||
|
// struct {
|
||||||
|
// __kernel_pid_t _pid; /* sender's pid */
|
||||||
|
// __ARCH_SI_UID_T _uid; /* sender's uid */
|
||||||
|
// } _kill;
|
||||||
|
//
|
||||||
|
// /* POSIX.1b timers */
|
||||||
|
// struct {
|
||||||
|
// __kernel_timer_t _tid; /* timer id */
|
||||||
|
// int _overrun; /* overrun count */
|
||||||
|
// char _pad[sizeof( __ARCH_SI_UID_T) - sizeof(int)];
|
||||||
|
// sigval_t _sigval; /* same as below */
|
||||||
|
// int _sys_private; /* not to be passed to user */
|
||||||
|
// } _timer;
|
||||||
|
//
|
||||||
|
// /* POSIX.1b signals */
|
||||||
|
// struct {
|
||||||
|
// __kernel_pid_t _pid; /* sender's pid */
|
||||||
|
// __ARCH_SI_UID_T _uid; /* sender's uid */
|
||||||
|
// sigval_t _sigval;
|
||||||
|
// } _rt;
|
||||||
|
//
|
||||||
|
// /* SIGCHLD */
|
||||||
|
// struct {
|
||||||
|
// __kernel_pid_t _pid; /* which child */
|
||||||
|
// __ARCH_SI_UID_T _uid; /* sender's uid */
|
||||||
|
// int _status; /* exit code */
|
||||||
|
// __ARCH_SI_CLOCK_T _utime;
|
||||||
|
// __ARCH_SI_CLOCK_T _stime;
|
||||||
|
// } _sigchld;
|
||||||
|
//
|
||||||
|
// /* SIGILL, SIGFPE, SIGSEGV, SIGBUS */
|
||||||
|
// struct {
|
||||||
|
// void *_addr; /* faulting insn/memory ref. */
|
||||||
|
// short _addr_lsb; /* LSB of the reported address */
|
||||||
|
// } _sigfault;
|
||||||
|
//
|
||||||
|
// /* SIGPOLL */
|
||||||
|
// struct {
|
||||||
|
// __ARCH_SI_BAND_T _band; /* POLL_IN, POLL_OUT, POLL_MSG */
|
||||||
|
// int _fd;
|
||||||
|
// } _sigpoll;
|
||||||
|
//
|
||||||
|
// /* SIGSYS */
|
||||||
|
// struct {
|
||||||
|
// void *_call_addr; /* calling user insn */
|
||||||
|
// int _syscall; /* triggering system call number */
|
||||||
|
// unsigned int _arch; /* AUDIT_ARCH_* of syscall */
|
||||||
|
// } _sigsys;
|
||||||
|
// } _sifields;
|
||||||
|
//
|
||||||
|
// _sifields is padded so that the size of siginfo is SI_MAX_SIZE = 128
|
||||||
|
// bytes.
|
||||||
|
Fields [128 - 16]byte
|
||||||
|
}
|
||||||
|
|
||||||
|
// FixSignalCodeForUser fixes up si_code.
|
||||||
|
//
|
||||||
|
// The si_code we get from Linux may contain the kernel-specific code in the
|
||||||
|
// top 16 bits if it's positive (e.g., from ptrace). Linux's
|
||||||
|
// copy_siginfo_to_user does:
|
||||||
|
// err |= __put_user((short)from->si_code, &to->si_code);
|
||||||
|
// to mask out those bits and we need to do the same.
|
||||||
|
func (s *SignalInfo) FixSignalCodeForUser() {
|
||||||
|
if s.Code > 0 {
|
||||||
|
s.Code &= 0x0000ffff
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// PID returns the si_pid field.
|
||||||
|
func (s *SignalInfo) PID() int32 {
|
||||||
|
return int32(hostarch.ByteOrder.Uint32(s.Fields[0:4]))
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetPID mutates the si_pid field.
|
||||||
|
func (s *SignalInfo) SetPID(val int32) {
|
||||||
|
hostarch.ByteOrder.PutUint32(s.Fields[0:4], uint32(val))
|
||||||
|
}
|
||||||
|
|
||||||
|
// UID returns the si_uid field.
|
||||||
|
func (s *SignalInfo) UID() int32 {
|
||||||
|
return int32(hostarch.ByteOrder.Uint32(s.Fields[4:8]))
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetUID mutates the si_uid field.
|
||||||
|
func (s *SignalInfo) SetUID(val int32) {
|
||||||
|
hostarch.ByteOrder.PutUint32(s.Fields[4:8], uint32(val))
|
||||||
|
}
|
||||||
|
|
||||||
|
// Sigval returns the sigval field, which is aliased to both si_int and si_ptr.
|
||||||
|
func (s *SignalInfo) Sigval() uint64 {
|
||||||
|
return hostarch.ByteOrder.Uint64(s.Fields[8:16])
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetSigval mutates the sigval field.
|
||||||
|
func (s *SignalInfo) SetSigval(val uint64) {
|
||||||
|
hostarch.ByteOrder.PutUint64(s.Fields[8:16], val)
|
||||||
|
}
|
||||||
|
|
||||||
|
// TimerID returns the si_timerid field.
|
||||||
|
func (s *SignalInfo) TimerID() TimerID {
|
||||||
|
return TimerID(hostarch.ByteOrder.Uint32(s.Fields[0:4]))
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetTimerID sets the si_timerid field.
|
||||||
|
func (s *SignalInfo) SetTimerID(val TimerID) {
|
||||||
|
hostarch.ByteOrder.PutUint32(s.Fields[0:4], uint32(val))
|
||||||
|
}
|
||||||
|
|
||||||
|
// Overrun returns the si_overrun field.
|
||||||
|
func (s *SignalInfo) Overrun() int32 {
|
||||||
|
return int32(hostarch.ByteOrder.Uint32(s.Fields[4:8]))
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetOverrun sets the si_overrun field.
|
||||||
|
func (s *SignalInfo) SetOverrun(val int32) {
|
||||||
|
hostarch.ByteOrder.PutUint32(s.Fields[4:8], uint32(val))
|
||||||
|
}
|
||||||
|
|
||||||
|
// Addr returns the si_addr field.
|
||||||
|
func (s *SignalInfo) Addr() uint64 {
|
||||||
|
return hostarch.ByteOrder.Uint64(s.Fields[0:8])
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetAddr sets the si_addr field.
|
||||||
|
func (s *SignalInfo) SetAddr(val uint64) {
|
||||||
|
hostarch.ByteOrder.PutUint64(s.Fields[0:8], val)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Status returns the si_status field.
|
||||||
|
func (s *SignalInfo) Status() int32 {
|
||||||
|
return int32(hostarch.ByteOrder.Uint32(s.Fields[8:12]))
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetStatus mutates the si_status field.
|
||||||
|
func (s *SignalInfo) SetStatus(val int32) {
|
||||||
|
hostarch.ByteOrder.PutUint32(s.Fields[8:12], uint32(val))
|
||||||
|
}
|
||||||
|
|
||||||
|
// CallAddr returns the si_call_addr field.
|
||||||
|
func (s *SignalInfo) CallAddr() uint64 {
|
||||||
|
return hostarch.ByteOrder.Uint64(s.Fields[0:8])
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetCallAddr mutates the si_call_addr field.
|
||||||
|
func (s *SignalInfo) SetCallAddr(val uint64) {
|
||||||
|
hostarch.ByteOrder.PutUint64(s.Fields[0:8], val)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Syscall returns the si_syscall field.
|
||||||
|
func (s *SignalInfo) Syscall() int32 {
|
||||||
|
return int32(hostarch.ByteOrder.Uint32(s.Fields[8:12]))
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetSyscall mutates the si_syscall field.
|
||||||
|
func (s *SignalInfo) SetSyscall(val int32) {
|
||||||
|
hostarch.ByteOrder.PutUint32(s.Fields[8:12], uint32(val))
|
||||||
|
}
|
||||||
|
|
||||||
|
// Arch returns the si_arch field.
|
||||||
|
func (s *SignalInfo) Arch() uint32 {
|
||||||
|
return hostarch.ByteOrder.Uint32(s.Fields[12:16])
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetArch mutates the si_arch field.
|
||||||
|
func (s *SignalInfo) SetArch(val uint32) {
|
||||||
|
hostarch.ByteOrder.PutUint32(s.Fields[12:16], val)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Band returns the si_band field.
|
||||||
|
func (s *SignalInfo) Band() int64 {
|
||||||
|
return int64(hostarch.ByteOrder.Uint64(s.Fields[0:8]))
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetBand mutates the si_band field.
|
||||||
|
func (s *SignalInfo) SetBand(val int64) {
|
||||||
|
// Note: this assumes the platform uses `long` as `__ARCH_SI_BAND_T`.
|
||||||
|
// On some platforms, which gVisor doesn't support, `__ARCH_SI_BAND_T` is
|
||||||
|
// `int`. See siginfo.h.
|
||||||
|
hostarch.ByteOrder.PutUint64(s.Fields[0:8], uint64(val))
|
||||||
|
}
|
||||||
|
|
||||||
|
// FD returns the si_fd field.
|
||||||
|
func (s *SignalInfo) FD() uint32 {
|
||||||
|
return hostarch.ByteOrder.Uint32(s.Fields[8:12])
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetFD mutates the si_fd field.
|
||||||
|
func (s *SignalInfo) SetFD(val uint32) {
|
||||||
|
hostarch.ByteOrder.PutUint32(s.Fields[8:12], val)
|
||||||
|
}
|
||||||
47
pkg/abi/linux/signalfd.go
Normal file
47
pkg/abi/linux/signalfd.go
Normal file
|
|
@ -0,0 +1,47 @@
|
||||||
|
// Copyright 2019 The gVisor 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 linux
|
||||||
|
|
||||||
|
const (
|
||||||
|
// SFD_NONBLOCK is a signalfd(2) flag.
|
||||||
|
SFD_NONBLOCK = 0o0004000
|
||||||
|
|
||||||
|
// SFD_CLOEXEC is a signalfd(2) flag.
|
||||||
|
SFD_CLOEXEC = 0o2000000
|
||||||
|
)
|
||||||
|
|
||||||
|
// SignalfdSiginfo is the siginfo encoding for signalfds.
|
||||||
|
//
|
||||||
|
// +marshal
|
||||||
|
type SignalfdSiginfo struct {
|
||||||
|
Signo uint32
|
||||||
|
Errno int32
|
||||||
|
Code int32
|
||||||
|
PID uint32
|
||||||
|
UID uint32
|
||||||
|
FD int32
|
||||||
|
TID uint32
|
||||||
|
Band uint32
|
||||||
|
Overrun uint32
|
||||||
|
TrapNo uint32
|
||||||
|
Status int32
|
||||||
|
Int int32
|
||||||
|
Ptr uint64
|
||||||
|
UTime uint64
|
||||||
|
STime uint64
|
||||||
|
Addr uint64
|
||||||
|
AddrLSB uint16
|
||||||
|
_ [48]uint8 `marshal:"unaligned"`
|
||||||
|
}
|
||||||
740
pkg/abi/linux/socket.go
Normal file
740
pkg/abi/linux/socket.go
Normal file
|
|
@ -0,0 +1,740 @@
|
||||||
|
// Copyright 2018 The gVisor 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 linux
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/sagernet/gvisor/pkg/marshal"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Address families, from linux/socket.h.
|
||||||
|
const (
|
||||||
|
AF_UNSPEC = 0
|
||||||
|
AF_UNIX = 1
|
||||||
|
AF_INET = 2
|
||||||
|
AF_AX25 = 3
|
||||||
|
AF_IPX = 4
|
||||||
|
AF_APPLETALK = 5
|
||||||
|
AF_NETROM = 6
|
||||||
|
AF_BRIDGE = 7
|
||||||
|
AF_ATMPVC = 8
|
||||||
|
AF_X25 = 9
|
||||||
|
AF_INET6 = 10
|
||||||
|
AF_ROSE = 11
|
||||||
|
AF_DECnet = 12
|
||||||
|
AF_NETBEUI = 13
|
||||||
|
AF_SECURITY = 14
|
||||||
|
AF_KEY = 15
|
||||||
|
AF_NETLINK = 16
|
||||||
|
AF_PACKET = 17
|
||||||
|
AF_ASH = 18
|
||||||
|
AF_ECONET = 19
|
||||||
|
AF_ATMSVC = 20
|
||||||
|
AF_RDS = 21
|
||||||
|
AF_SNA = 22
|
||||||
|
AF_IRDA = 23
|
||||||
|
AF_PPPOX = 24
|
||||||
|
AF_WANPIPE = 25
|
||||||
|
AF_LLC = 26
|
||||||
|
AF_IB = 27
|
||||||
|
AF_MPLS = 28
|
||||||
|
AF_CAN = 29
|
||||||
|
AF_TIPC = 30
|
||||||
|
AF_BLUETOOTH = 31
|
||||||
|
AF_IUCV = 32
|
||||||
|
AF_RXRPC = 33
|
||||||
|
AF_ISDN = 34
|
||||||
|
AF_PHONET = 35
|
||||||
|
AF_IEEE802154 = 36
|
||||||
|
AF_CAIF = 37
|
||||||
|
AF_ALG = 38
|
||||||
|
AF_NFC = 39
|
||||||
|
AF_VSOCK = 40
|
||||||
|
)
|
||||||
|
|
||||||
|
// sendmsg(2)/recvmsg(2) flags, from linux/socket.h.
|
||||||
|
const (
|
||||||
|
MSG_OOB = 0x1
|
||||||
|
MSG_PEEK = 0x2
|
||||||
|
MSG_DONTROUTE = 0x4
|
||||||
|
MSG_TRYHARD = 0x4
|
||||||
|
MSG_CTRUNC = 0x8
|
||||||
|
MSG_PROBE = 0x10
|
||||||
|
MSG_TRUNC = 0x20
|
||||||
|
MSG_DONTWAIT = 0x40
|
||||||
|
MSG_EOR = 0x80
|
||||||
|
MSG_WAITALL = 0x100
|
||||||
|
MSG_FIN = 0x200
|
||||||
|
MSG_EOF = MSG_FIN
|
||||||
|
MSG_SYN = 0x400
|
||||||
|
MSG_CONFIRM = 0x800
|
||||||
|
MSG_RST = 0x1000
|
||||||
|
MSG_ERRQUEUE = 0x2000
|
||||||
|
MSG_NOSIGNAL = 0x4000
|
||||||
|
MSG_MORE = 0x8000
|
||||||
|
MSG_WAITFORONE = 0x10000
|
||||||
|
MSG_SENDPAGE_NOTLAST = 0x20000
|
||||||
|
MSG_ZEROCOPY = 0x4000000
|
||||||
|
MSG_FASTOPEN = 0x20000000
|
||||||
|
MSG_CMSG_CLOEXEC = 0x40000000
|
||||||
|
)
|
||||||
|
|
||||||
|
// Set/get socket option levels, from socket.h.
|
||||||
|
const (
|
||||||
|
SOL_IP = 0
|
||||||
|
SOL_SOCKET = 1
|
||||||
|
SOL_TCP = 6
|
||||||
|
SOL_UDP = 17
|
||||||
|
SOL_IPV6 = 41
|
||||||
|
SOL_ICMPV6 = 58
|
||||||
|
SOL_RAW = 255
|
||||||
|
SOL_PACKET = 263
|
||||||
|
SOL_NETLINK = 270
|
||||||
|
)
|
||||||
|
|
||||||
|
// A SockType is a type (as opposed to family) of sockets. These are enumerated
|
||||||
|
// below as SOCK_* constants.
|
||||||
|
type SockType int
|
||||||
|
|
||||||
|
// Socket types, from linux/net.h.
|
||||||
|
const (
|
||||||
|
SOCK_STREAM SockType = 1
|
||||||
|
SOCK_DGRAM SockType = 2
|
||||||
|
SOCK_RAW SockType = 3
|
||||||
|
SOCK_RDM SockType = 4
|
||||||
|
SOCK_SEQPACKET SockType = 5
|
||||||
|
SOCK_DCCP SockType = 6
|
||||||
|
SOCK_PACKET SockType = 10
|
||||||
|
)
|
||||||
|
|
||||||
|
// SOCK_TYPE_MASK covers all of the above socket types. The remaining bits are
|
||||||
|
// flags. From linux/net.h.
|
||||||
|
const SOCK_TYPE_MASK = 0xf
|
||||||
|
|
||||||
|
// socket(2)/socketpair(2)/accept4(2) flags, from linux/net.h.
|
||||||
|
const (
|
||||||
|
SOCK_CLOEXEC = O_CLOEXEC
|
||||||
|
SOCK_NONBLOCK = O_NONBLOCK
|
||||||
|
)
|
||||||
|
|
||||||
|
// shutdown(2) how commands, from <linux/net.h>.
|
||||||
|
const (
|
||||||
|
SHUT_RD = 0
|
||||||
|
SHUT_WR = 1
|
||||||
|
SHUT_RDWR = 2
|
||||||
|
)
|
||||||
|
|
||||||
|
// Packet types from <linux/if_packet.h>
|
||||||
|
const (
|
||||||
|
PACKET_HOST = 0 // To us
|
||||||
|
PACKET_BROADCAST = 1 // To all
|
||||||
|
PACKET_MULTICAST = 2 // To group
|
||||||
|
PACKET_OTHERHOST = 3 // To someone else
|
||||||
|
PACKET_OUTGOING = 4 // Outgoing of any type
|
||||||
|
)
|
||||||
|
|
||||||
|
// Packet socket options from <linux/if_packet.h>
|
||||||
|
const (
|
||||||
|
PACKET_ADD_MEMBERSHIP = 1
|
||||||
|
PACKET_RX_RING = 5
|
||||||
|
PACKET_STATISTICS = 6
|
||||||
|
PACKET_AUXDATA = 8
|
||||||
|
PACKET_VERSION = 10
|
||||||
|
PACKET_HDRLEN = 11
|
||||||
|
PACKET_RESERVE = 12
|
||||||
|
)
|
||||||
|
|
||||||
|
// Statuses for a frame in a packet_mmap ring buffer from <linux/if_packet.h>.
|
||||||
|
const (
|
||||||
|
TP_STATUS_KERNEL = 0
|
||||||
|
TP_STATUS_USER = 0x1
|
||||||
|
TP_STATUS_COPY = 0x2
|
||||||
|
TP_STATUS_LOSING = 0x4
|
||||||
|
TP_STATUS_CSUM_NOT_READY = 0x8
|
||||||
|
TP_STATUS_VLAN_VALID = 0x10
|
||||||
|
TP_STATUS_BLK_TMO = 0x20
|
||||||
|
TP_STATUS_VLAN_TPID_VALID = 0x40
|
||||||
|
TP_STATUS_CSUM_VALID = 0x80
|
||||||
|
TP_STATUS_GSO_TCP = 0x100
|
||||||
|
)
|
||||||
|
|
||||||
|
// TpacketReq is the request for a packet_mmap ring buffer from
|
||||||
|
// <linux/if_packet.h>.
|
||||||
|
//
|
||||||
|
// +marshal
|
||||||
|
type TpacketReq struct {
|
||||||
|
TpBlockSize uint32
|
||||||
|
TpBlockNr uint32
|
||||||
|
TpFrameSize uint32
|
||||||
|
TpFrameNr uint32
|
||||||
|
}
|
||||||
|
|
||||||
|
// TpacketHdr is the header for a frame in a packet_mmap ring buffer from
|
||||||
|
// <linux/if_packet.h>.
|
||||||
|
//
|
||||||
|
// +marshal
|
||||||
|
type TpacketHdr struct {
|
||||||
|
TpStatus uint64
|
||||||
|
TpLen uint32
|
||||||
|
TpSnaplen uint32
|
||||||
|
TpMac uint16
|
||||||
|
TpNet uint16
|
||||||
|
TpSec uint32
|
||||||
|
TpUsec uint32
|
||||||
|
_ [4]uint8
|
||||||
|
}
|
||||||
|
|
||||||
|
// Tpacket2Hdr is the header for a frame in a packet_mmap ring buffer from
|
||||||
|
// <linux/if_packet.h>.
|
||||||
|
//
|
||||||
|
// +marshal
|
||||||
|
type Tpacket2Hdr struct {
|
||||||
|
TpStatus uint32
|
||||||
|
TpLen uint32
|
||||||
|
TpSnaplen uint32
|
||||||
|
TpMac uint16
|
||||||
|
TpNet uint16
|
||||||
|
TpSec uint32
|
||||||
|
TpNSec uint32
|
||||||
|
TpVlanTci uint16
|
||||||
|
TpVlanTpid uint16
|
||||||
|
_ [4]uint8
|
||||||
|
}
|
||||||
|
|
||||||
|
// TpacketStats is the statistics for a packet_mmap ring buffer from
|
||||||
|
// <linux/if_packet.h>.
|
||||||
|
//
|
||||||
|
// +marshal
|
||||||
|
type TpacketStats struct {
|
||||||
|
Packets uint32
|
||||||
|
Dropped uint32
|
||||||
|
}
|
||||||
|
|
||||||
|
// TpacketAlignment is the alignment of a frame in a packet_mmap ring buffer
|
||||||
|
// from <linux/if_packet.h>.
|
||||||
|
const (
|
||||||
|
TPACKET_ALIGNMENT = 16
|
||||||
|
)
|
||||||
|
|
||||||
|
// TPACKET_V1 is the version of a packet_mmap ring buffer from
|
||||||
|
// <linux/if_packet.h> that is implemented in gVisor.
|
||||||
|
const (
|
||||||
|
// TPACKET_V1 is the default version of PACKET_MMAP.
|
||||||
|
TPACKET_V1 = iota
|
||||||
|
// TPACKET_V2 is the version of PACKET_MMAP for tpacket2_hdr.
|
||||||
|
TPACKET_V2
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
// TPACKET_HDRLEN is the length of a TpacketHdr from <linux/if_packet.h>.
|
||||||
|
TPACKET_HDRLEN = TPacketAlign(uint32((*TpacketHdr)(nil).SizeBytes()) + uint32((*SockAddrLink)(nil).SizeBytes()))
|
||||||
|
// TPACKET2_HDRLEN is the length of a Tpacket2Hdr from <linux/if_packet.h>.
|
||||||
|
TPACKET2_HDRLEN = TPacketAlign(uint32((*Tpacket2Hdr)(nil).SizeBytes()) + uint32((*SockAddrLink)(nil).SizeBytes()))
|
||||||
|
)
|
||||||
|
|
||||||
|
// TPacketAlign aligns a value to the alignment of a TPacket.
|
||||||
|
func TPacketAlign(x uint32) uint32 {
|
||||||
|
return (x + TPACKET_ALIGNMENT - 1) &^ (TPACKET_ALIGNMENT - 1)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Socket options from socket.h.
|
||||||
|
const (
|
||||||
|
SO_DEBUG = 1
|
||||||
|
SO_REUSEADDR = 2
|
||||||
|
SO_TYPE = 3
|
||||||
|
SO_ERROR = 4
|
||||||
|
SO_DONTROUTE = 5
|
||||||
|
SO_BROADCAST = 6
|
||||||
|
SO_SNDBUF = 7
|
||||||
|
SO_RCVBUF = 8
|
||||||
|
SO_KEEPALIVE = 9
|
||||||
|
SO_OOBINLINE = 10
|
||||||
|
SO_NO_CHECK = 11
|
||||||
|
SO_PRIORITY = 12
|
||||||
|
SO_LINGER = 13
|
||||||
|
SO_BSDCOMPAT = 14
|
||||||
|
SO_REUSEPORT = 15
|
||||||
|
SO_PASSCRED = 16
|
||||||
|
SO_PEERCRED = 17
|
||||||
|
SO_RCVLOWAT = 18
|
||||||
|
SO_SNDLOWAT = 19
|
||||||
|
SO_RCVTIMEO = 20
|
||||||
|
SO_SNDTIMEO = 21
|
||||||
|
SO_BINDTODEVICE = 25
|
||||||
|
SO_ATTACH_FILTER = 26
|
||||||
|
SO_DETACH_FILTER = 27
|
||||||
|
SO_GET_FILTER = SO_ATTACH_FILTER
|
||||||
|
SO_PEERNAME = 28
|
||||||
|
SO_TIMESTAMP = 29
|
||||||
|
SO_ACCEPTCONN = 30
|
||||||
|
SO_PEERSEC = 31
|
||||||
|
SO_SNDBUFFORCE = 32
|
||||||
|
SO_RCVBUFFORCE = 33
|
||||||
|
SO_PASSSEC = 34
|
||||||
|
SO_TIMESTAMPNS = 35
|
||||||
|
SO_MARK = 36
|
||||||
|
SO_TIMESTAMPING = 37
|
||||||
|
SO_PROTOCOL = 38
|
||||||
|
SO_DOMAIN = 39
|
||||||
|
SO_RXQ_OVFL = 40
|
||||||
|
SO_WIFI_STATUS = 41
|
||||||
|
SO_PEEK_OFF = 42
|
||||||
|
SO_NOFCS = 43
|
||||||
|
SO_LOCK_FILTER = 44
|
||||||
|
SO_SELECT_ERR_QUEUE = 45
|
||||||
|
SO_BUSY_POLL = 46
|
||||||
|
SO_MAX_PACING_RATE = 47
|
||||||
|
SO_BPF_EXTENSIONS = 48
|
||||||
|
SO_INCOMING_CPU = 49
|
||||||
|
SO_ATTACH_BPF = 50
|
||||||
|
SO_ATTACH_REUSEPORT_CBPF = 51
|
||||||
|
SO_ATTACH_REUSEPORT_EBPF = 52
|
||||||
|
SO_CNX_ADVICE = 53
|
||||||
|
SO_MEMINFO = 55
|
||||||
|
SO_INCOMING_NAPI_ID = 56
|
||||||
|
SO_COOKIE = 57
|
||||||
|
SO_PEERGROUPS = 59
|
||||||
|
SO_ZEROCOPY = 60
|
||||||
|
SO_TXTIME = 61
|
||||||
|
SO_BINDTOIFINDEX = 62
|
||||||
|
SO_TIMESTAMP_OLD = 29
|
||||||
|
SO_TIMESTAMPNS_OLD = 35
|
||||||
|
SO_TIMESTAMPING_OLD = 37
|
||||||
|
SO_TIMESTAMP_NEW = 63
|
||||||
|
SO_TIMESTAMPNS_NEW = 64
|
||||||
|
SO_TIMESTAMPING_NEW = 65
|
||||||
|
SO_RCVTIMEO_NEW = 66
|
||||||
|
SO_SNDTIMEO_NEW = 67
|
||||||
|
SO_DETACH_REUSEPORT_BPF = 68
|
||||||
|
SO_PREFER_BUSY_POLL = 69
|
||||||
|
SO_BUSY_POLL_BUDGET = 70
|
||||||
|
SO_NETNS_COOKIE = 71
|
||||||
|
SO_BUF_LOCK = 72
|
||||||
|
SO_RESERVE_MEM = 73
|
||||||
|
SO_TXREHASH = 74
|
||||||
|
SO_RCVMARK = 75
|
||||||
|
SO_PASSPIDFD = 76
|
||||||
|
SO_PEERPIDFD = 77
|
||||||
|
SO_DEVMEM_LINEAR = 78
|
||||||
|
SO_DEVMEM_DMABUF = 79
|
||||||
|
SO_DEVMEM_DONTNEED = 80
|
||||||
|
SO_RCVPRIORITY = 82
|
||||||
|
)
|
||||||
|
|
||||||
|
// enum socket_state, from uapi/linux/net.h.
|
||||||
|
const (
|
||||||
|
SS_FREE = 0 // Not allocated.
|
||||||
|
SS_UNCONNECTED = 1 // Unconnected to any socket.
|
||||||
|
SS_CONNECTING = 2 // In process of connecting.
|
||||||
|
SS_CONNECTED = 3 // Connected to socket.
|
||||||
|
SS_DISCONNECTING = 4 // In process of disconnecting.
|
||||||
|
)
|
||||||
|
|
||||||
|
// TCP protocol states, from include/net/tcp_states.h.
|
||||||
|
const (
|
||||||
|
TCP_ESTABLISHED uint32 = iota + 1
|
||||||
|
TCP_SYN_SENT
|
||||||
|
TCP_SYN_RECV
|
||||||
|
TCP_FIN_WAIT1
|
||||||
|
TCP_FIN_WAIT2
|
||||||
|
TCP_TIME_WAIT
|
||||||
|
TCP_CLOSE
|
||||||
|
TCP_CLOSE_WAIT
|
||||||
|
TCP_LAST_ACK
|
||||||
|
TCP_LISTEN
|
||||||
|
TCP_CLOSING
|
||||||
|
TCP_NEW_SYN_RECV
|
||||||
|
)
|
||||||
|
|
||||||
|
// SockAddrMax is the maximum size of a struct sockaddr, from
|
||||||
|
// uapi/linux/socket.h.
|
||||||
|
const SockAddrMax = 128
|
||||||
|
|
||||||
|
// InetAddr is struct in_addr, from uapi/linux/in.h.
|
||||||
|
//
|
||||||
|
// +marshal
|
||||||
|
type InetAddr [4]byte
|
||||||
|
|
||||||
|
// SizeOfInetAddr is the size of InetAddr.
|
||||||
|
var SizeOfInetAddr = uint32((*InetAddr)(nil).SizeBytes())
|
||||||
|
|
||||||
|
// SockAddrInet is struct sockaddr_in, from uapi/linux/in.h.
|
||||||
|
//
|
||||||
|
// +marshal
|
||||||
|
type SockAddrInet struct {
|
||||||
|
Family uint16
|
||||||
|
Port uint16
|
||||||
|
Addr InetAddr
|
||||||
|
_ [8]uint8 // pad to sizeof(struct sockaddr).
|
||||||
|
}
|
||||||
|
|
||||||
|
// Inet6MulticastRequest is struct ipv6_mreq, from uapi/linux/in6.h.
|
||||||
|
//
|
||||||
|
// +marshal
|
||||||
|
type Inet6MulticastRequest struct {
|
||||||
|
MulticastAddr Inet6Addr
|
||||||
|
InterfaceIndex int32
|
||||||
|
}
|
||||||
|
|
||||||
|
// InetMulticastRequest is struct ip_mreq, from uapi/linux/in.h.
|
||||||
|
//
|
||||||
|
// +marshal
|
||||||
|
type InetMulticastRequest struct {
|
||||||
|
MulticastAddr InetAddr
|
||||||
|
InterfaceAddr InetAddr
|
||||||
|
}
|
||||||
|
|
||||||
|
// InetMulticastRequestWithNIC is struct ip_mreqn, from uapi/linux/in.h.
|
||||||
|
//
|
||||||
|
// +marshal
|
||||||
|
type InetMulticastRequestWithNIC struct {
|
||||||
|
InetMulticastRequest
|
||||||
|
InterfaceIndex int32
|
||||||
|
}
|
||||||
|
|
||||||
|
// Inet6Addr is struct in6_addr, from uapi/linux/in6.h.
|
||||||
|
//
|
||||||
|
// +marshal
|
||||||
|
type Inet6Addr [16]byte
|
||||||
|
|
||||||
|
// SockAddrInet6 is struct sockaddr_in6, from uapi/linux/in6.h.
|
||||||
|
//
|
||||||
|
// +marshal
|
||||||
|
type SockAddrInet6 struct {
|
||||||
|
Family uint16
|
||||||
|
Port uint16
|
||||||
|
Flowinfo uint32
|
||||||
|
Addr [16]byte
|
||||||
|
Scope_id uint32
|
||||||
|
}
|
||||||
|
|
||||||
|
// SockAddrLink is a struct sockaddr_ll, from uapi/linux/if_packet.h.
|
||||||
|
//
|
||||||
|
// +marshal
|
||||||
|
type SockAddrLink struct {
|
||||||
|
Family uint16
|
||||||
|
Protocol uint16
|
||||||
|
InterfaceIndex int32
|
||||||
|
ARPHardwareType uint16
|
||||||
|
PacketType byte
|
||||||
|
HardwareAddrLen byte
|
||||||
|
HardwareAddr [8]byte
|
||||||
|
}
|
||||||
|
|
||||||
|
// UnixPathMax is the maximum length of the path in an AF_UNIX socket.
|
||||||
|
//
|
||||||
|
// From uapi/linux/un.h.
|
||||||
|
const UnixPathMax = 108
|
||||||
|
|
||||||
|
// SockAddrUnix is struct sockaddr_un, from uapi/linux/un.h.
|
||||||
|
//
|
||||||
|
// +marshal
|
||||||
|
type SockAddrUnix struct {
|
||||||
|
Family uint16
|
||||||
|
Path [UnixPathMax]int8
|
||||||
|
}
|
||||||
|
|
||||||
|
// SockAddr represents a union of valid socket address types. This is logically
|
||||||
|
// equivalent to struct sockaddr. SockAddr ensures that a well-defined set of
|
||||||
|
// types can be used as socket addresses.
|
||||||
|
type SockAddr interface {
|
||||||
|
marshal.Marshallable
|
||||||
|
|
||||||
|
// implementsSockAddr exists purely to allow a type to indicate that they
|
||||||
|
// implement this interface. This method is a no-op and shouldn't be called.
|
||||||
|
implementsSockAddr()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *SockAddrInet) implementsSockAddr() {}
|
||||||
|
func (s *SockAddrInet6) implementsSockAddr() {}
|
||||||
|
func (s *SockAddrLink) implementsSockAddr() {}
|
||||||
|
func (s *SockAddrUnix) implementsSockAddr() {}
|
||||||
|
func (s *SockAddrNetlink) implementsSockAddr() {}
|
||||||
|
|
||||||
|
// Linger is struct linger, from include/linux/socket.h.
|
||||||
|
//
|
||||||
|
// +marshal
|
||||||
|
type Linger struct {
|
||||||
|
OnOff int32
|
||||||
|
Linger int32
|
||||||
|
}
|
||||||
|
|
||||||
|
// SizeOfLinger is the binary size of a Linger struct.
|
||||||
|
const SizeOfLinger = 8
|
||||||
|
|
||||||
|
// TCPInfo is a collection of TCP statistics.
|
||||||
|
//
|
||||||
|
// From uapi/linux/tcp.h. Newer versions of Linux continue to add new fields to
|
||||||
|
// the end of this struct or within existing unused space, so its size grows
|
||||||
|
// over time. The current iteration is based on linux v4.17. New versions are
|
||||||
|
// always backwards compatible.
|
||||||
|
//
|
||||||
|
// +marshal
|
||||||
|
type TCPInfo struct {
|
||||||
|
// State is the state of the connection.
|
||||||
|
State uint8
|
||||||
|
|
||||||
|
// CaState is the congestion control state.
|
||||||
|
CaState uint8
|
||||||
|
|
||||||
|
// Retransmits is the number of retransmissions triggered by RTO.
|
||||||
|
Retransmits uint8
|
||||||
|
|
||||||
|
// Probes is the number of unanswered zero window probes.
|
||||||
|
Probes uint8
|
||||||
|
|
||||||
|
// BackOff indicates exponential backoff.
|
||||||
|
Backoff uint8
|
||||||
|
|
||||||
|
// Options indicates the options enabled for the connection.
|
||||||
|
Options uint8
|
||||||
|
|
||||||
|
// WindowScale is the combination of snd_wscale (first 4 bits) and
|
||||||
|
// rcv_wscale (second 4 bits)
|
||||||
|
WindowScale uint8
|
||||||
|
|
||||||
|
// DeliveryRateAppLimited is a boolean and only the first bit is
|
||||||
|
// meaningful.
|
||||||
|
DeliveryRateAppLimited uint8
|
||||||
|
|
||||||
|
// RTO is the retransmission timeout.
|
||||||
|
RTO uint32
|
||||||
|
|
||||||
|
// ATO is the acknowledgement timeout interval.
|
||||||
|
ATO uint32
|
||||||
|
|
||||||
|
// SndMss is the send maximum segment size.
|
||||||
|
SndMss uint32
|
||||||
|
|
||||||
|
// RcvMss is the receive maximum segment size.
|
||||||
|
RcvMss uint32
|
||||||
|
|
||||||
|
// Unacked is the number of packets sent but not acknowledged.
|
||||||
|
Unacked uint32
|
||||||
|
|
||||||
|
// Sacked is the number of packets which are selectively acknowledged.
|
||||||
|
Sacked uint32
|
||||||
|
|
||||||
|
// Lost is the number of packets marked as lost.
|
||||||
|
Lost uint32
|
||||||
|
|
||||||
|
// Retrans is the number of retransmitted packets.
|
||||||
|
Retrans uint32
|
||||||
|
|
||||||
|
// Fackets is not used and is always zero.
|
||||||
|
Fackets uint32
|
||||||
|
|
||||||
|
// Times.
|
||||||
|
LastDataSent uint32
|
||||||
|
LastAckSent uint32
|
||||||
|
LastDataRecv uint32
|
||||||
|
LastAckRecv uint32
|
||||||
|
|
||||||
|
// Metrics.
|
||||||
|
PMTU uint32
|
||||||
|
RcvSsthresh uint32
|
||||||
|
RTT uint32
|
||||||
|
RTTVar uint32
|
||||||
|
SndSsthresh uint32
|
||||||
|
SndCwnd uint32
|
||||||
|
Advmss uint32
|
||||||
|
Reordering uint32
|
||||||
|
|
||||||
|
// RcvRTT is the receiver round trip time.
|
||||||
|
RcvRTT uint32
|
||||||
|
|
||||||
|
// RcvSpace is the current buffer space available for receiving data.
|
||||||
|
RcvSpace uint32
|
||||||
|
|
||||||
|
// TotalRetrans is the total number of retransmits seen since the start
|
||||||
|
// of the connection.
|
||||||
|
TotalRetrans uint32
|
||||||
|
|
||||||
|
// PacingRate is the pacing rate in bytes per second.
|
||||||
|
PacingRate uint64
|
||||||
|
|
||||||
|
// MaxPacingRate is the maximum pacing rate.
|
||||||
|
MaxPacingRate uint64
|
||||||
|
|
||||||
|
// BytesAcked is RFC4898 tcpEStatsAppHCThruOctetsAcked.
|
||||||
|
BytesAcked uint64
|
||||||
|
|
||||||
|
// BytesReceived is RFC4898 tcpEStatsAppHCThruOctetsReceived.
|
||||||
|
BytesReceived uint64
|
||||||
|
|
||||||
|
// SegsOut is RFC4898 tcpEStatsPerfSegsOut.
|
||||||
|
SegsOut uint32
|
||||||
|
|
||||||
|
// SegsIn is RFC4898 tcpEStatsPerfSegsIn.
|
||||||
|
SegsIn uint32
|
||||||
|
|
||||||
|
// NotSentBytes is the amount of bytes in the write queue that are not
|
||||||
|
// yet sent.
|
||||||
|
NotSentBytes uint32
|
||||||
|
|
||||||
|
// MinRTT is the minimum round trip time seen in the connection.
|
||||||
|
MinRTT uint32
|
||||||
|
|
||||||
|
// DataSegsIn is RFC4898 tcpEStatsDataSegsIn.
|
||||||
|
DataSegsIn uint32
|
||||||
|
|
||||||
|
// DataSegsOut is RFC4898 tcpEStatsDataSegsOut.
|
||||||
|
DataSegsOut uint32
|
||||||
|
|
||||||
|
// DeliveryRate is the most recent delivery rate in bytes per second.
|
||||||
|
DeliveryRate uint64
|
||||||
|
|
||||||
|
// BusyTime is the time in microseconds busy sending data.
|
||||||
|
BusyTime uint64
|
||||||
|
|
||||||
|
// RwndLimited is the time in microseconds limited by receive window.
|
||||||
|
RwndLimited uint64
|
||||||
|
|
||||||
|
// SndBufLimited is the time in microseconds limited by send buffer.
|
||||||
|
SndBufLimited uint64
|
||||||
|
|
||||||
|
// Delivered is the total data packets delivered including retransmits.
|
||||||
|
Delivered uint32
|
||||||
|
|
||||||
|
// DeliveredCE is the total ECE marked data packets delivered including
|
||||||
|
// retransmits.
|
||||||
|
DeliveredCE uint32
|
||||||
|
|
||||||
|
// BytesSent is RFC4898 tcpEStatsPerfHCDataOctetsOut.
|
||||||
|
BytesSent uint64
|
||||||
|
|
||||||
|
// BytesRetrans is RFC4898 tcpEStatsPerfOctetsRetrans.
|
||||||
|
BytesRetrans uint64
|
||||||
|
|
||||||
|
// DSACKDups is RFC4898 tcpEStatsStackDSACKDups.
|
||||||
|
DSACKDups uint32
|
||||||
|
|
||||||
|
// ReordSeen is the number of reordering events seen since the start of
|
||||||
|
// the connection.
|
||||||
|
ReordSeen uint32
|
||||||
|
}
|
||||||
|
|
||||||
|
// SizeOfTCPInfo is the binary size of a TCPInfo struct.
|
||||||
|
var SizeOfTCPInfo = (*TCPInfo)(nil).SizeBytes()
|
||||||
|
|
||||||
|
// Control message types, from linux/socket.h.
|
||||||
|
const (
|
||||||
|
SCM_CREDENTIALS = 0x2
|
||||||
|
SCM_RIGHTS = 0x1
|
||||||
|
)
|
||||||
|
|
||||||
|
// A ControlMessageHeader is the header for a socket control message.
|
||||||
|
//
|
||||||
|
// ControlMessageHeader represents struct cmsghdr from linux/socket.h.
|
||||||
|
//
|
||||||
|
// +marshal
|
||||||
|
type ControlMessageHeader struct {
|
||||||
|
Length uint64
|
||||||
|
Level int32
|
||||||
|
Type int32
|
||||||
|
}
|
||||||
|
|
||||||
|
// SizeOfControlMessageHeader is the binary size of a ControlMessageHeader
|
||||||
|
// struct.
|
||||||
|
var SizeOfControlMessageHeader = (*ControlMessageHeader)(nil).SizeBytes()
|
||||||
|
|
||||||
|
// A ControlMessageCredentials is an SCM_CREDENTIALS socket control message.
|
||||||
|
//
|
||||||
|
// ControlMessageCredentials represents struct ucred from linux/socket.h.
|
||||||
|
//
|
||||||
|
// +marshal
|
||||||
|
type ControlMessageCredentials struct {
|
||||||
|
PID int32
|
||||||
|
UID uint32
|
||||||
|
GID uint32
|
||||||
|
}
|
||||||
|
|
||||||
|
// A ControlMessageIPPacketInfo is IP_PKTINFO socket control message.
|
||||||
|
//
|
||||||
|
// ControlMessageIPPacketInfo represents struct in_pktinfo from linux/in.h.
|
||||||
|
//
|
||||||
|
// +marshal
|
||||||
|
// +stateify savable
|
||||||
|
type ControlMessageIPPacketInfo struct {
|
||||||
|
NIC int32
|
||||||
|
LocalAddr InetAddr
|
||||||
|
DestinationAddr InetAddr
|
||||||
|
}
|
||||||
|
|
||||||
|
// ControlMessageIPv6PacketInfo represents struct in6_pktinfo from linux/ipv6.h.
|
||||||
|
//
|
||||||
|
// +marshal
|
||||||
|
// +stateify savable
|
||||||
|
type ControlMessageIPv6PacketInfo struct {
|
||||||
|
Addr Inet6Addr
|
||||||
|
NIC uint32
|
||||||
|
}
|
||||||
|
|
||||||
|
// SizeOfControlMessageCredentials is the binary size of a
|
||||||
|
// ControlMessageCredentials struct.
|
||||||
|
var SizeOfControlMessageCredentials = (*ControlMessageCredentials)(nil).SizeBytes()
|
||||||
|
|
||||||
|
// SizeOfControlMessageRight is the size of a single element in
|
||||||
|
// ControlMessageRights.
|
||||||
|
const SizeOfControlMessageRight = 4
|
||||||
|
|
||||||
|
// SizeOfControlMessageInq is the size of a TCP_INQ control message.
|
||||||
|
const SizeOfControlMessageInq = 4
|
||||||
|
|
||||||
|
// SizeOfControlMessageTOS is the size of an IP_TOS control message.
|
||||||
|
const SizeOfControlMessageTOS = 1
|
||||||
|
|
||||||
|
// SizeOfControlMessageTTL is the size of an IP_TTL control message.
|
||||||
|
const SizeOfControlMessageTTL = 4
|
||||||
|
|
||||||
|
// SizeOfControlMessageTClass is the size of an IPV6_TCLASS control message.
|
||||||
|
const SizeOfControlMessageTClass = 4
|
||||||
|
|
||||||
|
// SizeOfControlMessageHopLimit is the size of an IPV6_HOPLIMIT control message.
|
||||||
|
const SizeOfControlMessageHopLimit = 4
|
||||||
|
|
||||||
|
// SizeOfControlMessageIPPacketInfo is the size of an IP_PKTINFO control
|
||||||
|
// message.
|
||||||
|
const SizeOfControlMessageIPPacketInfo = 12
|
||||||
|
|
||||||
|
// SizeOfControlMessageIPv6PacketInfo is the size of a
|
||||||
|
// ControlMessageIPv6PacketInfo.
|
||||||
|
const SizeOfControlMessageIPv6PacketInfo = 20
|
||||||
|
|
||||||
|
// SCM_MAX_FD is the maximum number of FDs accepted in a single sendmsg call.
|
||||||
|
// From net/scm.h.
|
||||||
|
const SCM_MAX_FD = 253
|
||||||
|
|
||||||
|
// SO_ACCEPTCON is defined as __SO_ACCEPTCON in
|
||||||
|
// include/uapi/linux/net.h, which represents a listening socket
|
||||||
|
// state. Note that this is distinct from SO_ACCEPTCONN, which is a
|
||||||
|
// socket option for querying whether a socket is in a listening
|
||||||
|
// state.
|
||||||
|
const SO_ACCEPTCON = 1 << 16
|
||||||
|
|
||||||
|
// ICMP6Filter represents struct icmp6_filter from linux/icmpv6.h.
|
||||||
|
//
|
||||||
|
// +marshal
|
||||||
|
// +stateify savable
|
||||||
|
type ICMP6Filter struct {
|
||||||
|
Filter [8]uint32
|
||||||
|
}
|
||||||
|
|
||||||
|
// Size of corresponding structs.
|
||||||
|
var (
|
||||||
|
ICMP6FilterSize = (*ICMP6Filter)(nil).SizeBytes()
|
||||||
|
SockAddrInetSize = (*SockAddrInet)(nil).SizeBytes()
|
||||||
|
SockAddrInet6Size = (*SockAddrInet6)(nil).SizeBytes()
|
||||||
|
SockAddrLinkSize = (*SockAddrLink)(nil).SizeBytes()
|
||||||
|
)
|
||||||
23
pkg/abi/linux/splice.go
Normal file
23
pkg/abi/linux/splice.go
Normal file
|
|
@ -0,0 +1,23 @@
|
||||||
|
// Copyright 2019 The gVisor 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 linux
|
||||||
|
|
||||||
|
// Constants for splice(2), sendfile(2) and tee(2).
|
||||||
|
const (
|
||||||
|
SPLICE_F_MOVE = 1 << iota
|
||||||
|
SPLICE_F_NONBLOCK
|
||||||
|
SPLICE_F_MORE
|
||||||
|
SPLICE_F_GIFT
|
||||||
|
)
|
||||||
71
pkg/abi/linux/tcp.go
Normal file
71
pkg/abi/linux/tcp.go
Normal file
|
|
@ -0,0 +1,71 @@
|
||||||
|
// Copyright 2018 The gVisor 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 linux
|
||||||
|
|
||||||
|
// Socket options from uapi/linux/tcp.h.
|
||||||
|
const (
|
||||||
|
TCP_NODELAY = 1
|
||||||
|
TCP_MAXSEG = 2
|
||||||
|
TCP_CORK = 3
|
||||||
|
TCP_KEEPIDLE = 4
|
||||||
|
TCP_KEEPINTVL = 5
|
||||||
|
TCP_KEEPCNT = 6
|
||||||
|
TCP_SYNCNT = 7
|
||||||
|
TCP_LINGER2 = 8
|
||||||
|
TCP_DEFER_ACCEPT = 9
|
||||||
|
TCP_WINDOW_CLAMP = 10
|
||||||
|
TCP_INFO = 11
|
||||||
|
TCP_QUICKACK = 12
|
||||||
|
TCP_CONGESTION = 13
|
||||||
|
TCP_MD5SIG = 14
|
||||||
|
TCP_THIN_LINEAR_TIMEOUTS = 16
|
||||||
|
TCP_THIN_DUPACK = 17
|
||||||
|
TCP_USER_TIMEOUT = 18
|
||||||
|
TCP_REPAIR = 19
|
||||||
|
TCP_REPAIR_QUEUE = 20
|
||||||
|
TCP_QUEUE_SEQ = 21
|
||||||
|
TCP_REPAIR_OPTIONS = 22
|
||||||
|
TCP_FASTOPEN = 23
|
||||||
|
TCP_TIMESTAMP = 24
|
||||||
|
TCP_NOTSENT_LOWAT = 25
|
||||||
|
TCP_CC_INFO = 26
|
||||||
|
TCP_SAVE_SYN = 27
|
||||||
|
TCP_SAVED_SYN = 28
|
||||||
|
TCP_REPAIR_WINDOW = 29
|
||||||
|
TCP_FASTOPEN_CONNECT = 30
|
||||||
|
TCP_ULP = 31
|
||||||
|
TCP_MD5SIG_EXT = 32
|
||||||
|
TCP_FASTOPEN_KEY = 33
|
||||||
|
TCP_FASTOPEN_NO_COOKIE = 34
|
||||||
|
TCP_ZEROCOPY_RECEIVE = 35
|
||||||
|
TCP_INQ = 36
|
||||||
|
TCP_TX_DELAY = 37
|
||||||
|
)
|
||||||
|
|
||||||
|
// Socket constants from include/net/tcp.h.
|
||||||
|
const (
|
||||||
|
MAX_TCP_KEEPIDLE = 32767
|
||||||
|
MAX_TCP_KEEPINTVL = 32767
|
||||||
|
MAX_TCP_KEEPCNT = 127
|
||||||
|
)
|
||||||
|
|
||||||
|
// Congestion control states from include/uapi/linux/tcp.h.
|
||||||
|
const (
|
||||||
|
TCP_CA_Open = 0
|
||||||
|
TCP_CA_Disorder = 1
|
||||||
|
TCP_CA_CWR = 2
|
||||||
|
TCP_CA_Recovery = 3
|
||||||
|
TCP_CA_Loss = 4
|
||||||
|
)
|
||||||
288
pkg/abi/linux/time.go
Normal file
288
pkg/abi/linux/time.go
Normal file
|
|
@ -0,0 +1,288 @@
|
||||||
|
// Copyright 2018 The gVisor 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 linux
|
||||||
|
|
||||||
|
import (
|
||||||
|
"math"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
// ClockTick is the length of time represented by a single clock tick, as
|
||||||
|
// used by times(2) and /proc/[pid]/stat.
|
||||||
|
ClockTick = time.Second / CLOCKS_PER_SEC
|
||||||
|
|
||||||
|
// CLOCKS_PER_SEC is the number of ClockTicks per second.
|
||||||
|
//
|
||||||
|
// Linux defines this to be 100 on most architectures, irrespective of
|
||||||
|
// CONFIG_HZ. Userspace obtains the value through sysconf(_SC_CLK_TCK),
|
||||||
|
// which uses the AT_CLKTCK entry in the auxiliary vector if one is
|
||||||
|
// provided, and assumes 100 otherwise (glibc:
|
||||||
|
// sysdeps/posix/sysconf.c:__sysconf() =>
|
||||||
|
// sysdeps/unix/sysv/linux/getclktck.c, elf/dl-support.c:_dl_aux_init()).
|
||||||
|
//
|
||||||
|
// Not to be confused with POSIX CLOCKS_PER_SEC, as used by clock(3); "XSI
|
||||||
|
// requires that [POSIX] CLOCKS_PER_SEC equals 1000000 independent of the
|
||||||
|
// actual resolution" - clock(3).
|
||||||
|
CLOCKS_PER_SEC = 100
|
||||||
|
)
|
||||||
|
|
||||||
|
// CPU clock types for use with clock_gettime(2) et al.
|
||||||
|
//
|
||||||
|
// The 29 most significant bits of a 32 bit clock ID are either a PID or a FD.
|
||||||
|
//
|
||||||
|
// Bits 1 and 0 give the type: PROF=0, VIRT=1, SCHED=2, or FD=3.
|
||||||
|
//
|
||||||
|
// Bit 2 indicates whether a cpu clock refers to a thread or a process.
|
||||||
|
const (
|
||||||
|
CPUCLOCK_PROF = 0
|
||||||
|
CPUCLOCK_VIRT = 1
|
||||||
|
CPUCLOCK_SCHED = 2
|
||||||
|
CPUCLOCK_MAX = 3
|
||||||
|
CLOCKFD = CPUCLOCK_MAX
|
||||||
|
|
||||||
|
CPUCLOCK_CLOCK_MASK = 3
|
||||||
|
CPUCLOCK_PERTHREAD_MASK = 4
|
||||||
|
)
|
||||||
|
|
||||||
|
// Clock identifiers for use with clock_gettime(2), clock_getres(2),
|
||||||
|
// clock_nanosleep(2).
|
||||||
|
const (
|
||||||
|
CLOCK_REALTIME = 0
|
||||||
|
CLOCK_MONOTONIC = 1
|
||||||
|
CLOCK_PROCESS_CPUTIME_ID = 2
|
||||||
|
CLOCK_THREAD_CPUTIME_ID = 3
|
||||||
|
CLOCK_MONOTONIC_RAW = 4
|
||||||
|
CLOCK_REALTIME_COARSE = 5
|
||||||
|
CLOCK_MONOTONIC_COARSE = 6
|
||||||
|
CLOCK_BOOTTIME = 7
|
||||||
|
CLOCK_REALTIME_ALARM = 8
|
||||||
|
CLOCK_BOOTTIME_ALARM = 9
|
||||||
|
)
|
||||||
|
|
||||||
|
// Flags for clock_nanosleep(2).
|
||||||
|
const (
|
||||||
|
TIMER_ABSTIME = 1
|
||||||
|
)
|
||||||
|
|
||||||
|
// Flags for timerfd syscalls (timerfd_create(2), timerfd_settime(2)).
|
||||||
|
const (
|
||||||
|
// TFD_CLOEXEC is a timerfd_create flag.
|
||||||
|
TFD_CLOEXEC = O_CLOEXEC
|
||||||
|
|
||||||
|
// TFD_NONBLOCK is a timerfd_create flag.
|
||||||
|
TFD_NONBLOCK = O_NONBLOCK
|
||||||
|
|
||||||
|
// TFD_TIMER_ABSTIME is a timerfd_settime flag.
|
||||||
|
TFD_TIMER_ABSTIME = 1
|
||||||
|
)
|
||||||
|
|
||||||
|
// The safe number of seconds you can represent by int64.
|
||||||
|
const maxSecInDuration = math.MaxInt64 / int64(time.Second)
|
||||||
|
|
||||||
|
// TimeT represents time_t in <time.h>. It represents time in seconds.
|
||||||
|
//
|
||||||
|
// +marshal
|
||||||
|
type TimeT int64
|
||||||
|
|
||||||
|
// NsecToTimeT translates nanoseconds to TimeT (seconds).
|
||||||
|
func NsecToTimeT(nsec int64) TimeT {
|
||||||
|
return TimeT(nsec / 1e9)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Timespec represents struct timespec in <time.h>.
|
||||||
|
//
|
||||||
|
// +marshal slice:TimespecSlice
|
||||||
|
type Timespec struct {
|
||||||
|
Sec int64
|
||||||
|
Nsec int64
|
||||||
|
}
|
||||||
|
|
||||||
|
// Unix returns the second and nanosecond.
|
||||||
|
func (ts Timespec) Unix() (sec int64, nsec int64) {
|
||||||
|
return int64(ts.Sec), int64(ts.Nsec)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ToTime returns the Go time.Time representation.
|
||||||
|
func (ts Timespec) ToTime() time.Time {
|
||||||
|
return time.Unix(ts.Sec, ts.Nsec)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ToNsec returns the nanosecond representation.
|
||||||
|
func (ts Timespec) ToNsec() int64 {
|
||||||
|
return int64(ts.Sec)*1e9 + int64(ts.Nsec)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ToNsecCapped returns the safe nanosecond representation.
|
||||||
|
func (ts Timespec) ToNsecCapped() int64 {
|
||||||
|
if ts.Sec > maxSecInDuration {
|
||||||
|
return math.MaxInt64
|
||||||
|
}
|
||||||
|
return ts.ToNsec()
|
||||||
|
}
|
||||||
|
|
||||||
|
// ToDuration returns the safe nanosecond representation as time.Duration.
|
||||||
|
func (ts Timespec) ToDuration() time.Duration {
|
||||||
|
return time.Duration(ts.ToNsecCapped())
|
||||||
|
}
|
||||||
|
|
||||||
|
// Valid returns whether the timespec contains valid values.
|
||||||
|
func (ts Timespec) Valid() bool {
|
||||||
|
return !(ts.Sec < 0 || ts.Nsec < 0 || ts.Nsec >= int64(time.Second))
|
||||||
|
}
|
||||||
|
|
||||||
|
// NsecToTimespec translates nanoseconds to Timespec.
|
||||||
|
func NsecToTimespec(nsec int64) (ts Timespec) {
|
||||||
|
ts.Sec = nsec / 1e9
|
||||||
|
ts.Nsec = nsec % 1e9
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// DurationToTimespec translates time.Duration to Timespec.
|
||||||
|
func DurationToTimespec(dur time.Duration) Timespec {
|
||||||
|
return NsecToTimespec(dur.Nanoseconds())
|
||||||
|
}
|
||||||
|
|
||||||
|
// SizeOfTimeval is the size of a Timeval struct in bytes.
|
||||||
|
const SizeOfTimeval = 16
|
||||||
|
|
||||||
|
// Timeval represents struct timeval in <time.h>.
|
||||||
|
//
|
||||||
|
// +marshal slice:TimevalSlice
|
||||||
|
type Timeval struct {
|
||||||
|
Sec int64
|
||||||
|
Usec int64
|
||||||
|
}
|
||||||
|
|
||||||
|
// ToNsecCapped returns the safe nanosecond representation.
|
||||||
|
func (tv Timeval) ToNsecCapped() int64 {
|
||||||
|
if tv.Sec > maxSecInDuration {
|
||||||
|
return math.MaxInt64
|
||||||
|
}
|
||||||
|
return int64(tv.Sec)*1e9 + int64(tv.Usec)*1e3
|
||||||
|
}
|
||||||
|
|
||||||
|
// ToDuration returns the safe nanosecond representation as a time.Duration.
|
||||||
|
func (tv Timeval) ToDuration() time.Duration {
|
||||||
|
return time.Duration(tv.ToNsecCapped())
|
||||||
|
}
|
||||||
|
|
||||||
|
// ToTime returns the Go time.Time representation.
|
||||||
|
func (tv Timeval) ToTime() time.Time {
|
||||||
|
return time.Unix(tv.Sec, tv.Usec*1e3)
|
||||||
|
}
|
||||||
|
|
||||||
|
// NsecToTimeval translates nanosecond to Timeval.
|
||||||
|
func NsecToTimeval(nsec int64) (tv Timeval) {
|
||||||
|
nsec += 999 // round up to microsecond
|
||||||
|
tv.Sec = nsec / 1e9
|
||||||
|
tv.Usec = nsec % 1e9 / 1e3
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// DurationToTimeval translates time.Duration to Timeval.
|
||||||
|
func DurationToTimeval(dur time.Duration) Timeval {
|
||||||
|
return NsecToTimeval(dur.Nanoseconds())
|
||||||
|
}
|
||||||
|
|
||||||
|
// Itimerspec represents struct itimerspec in <time.h>.
|
||||||
|
//
|
||||||
|
// +marshal
|
||||||
|
type Itimerspec struct {
|
||||||
|
Interval Timespec
|
||||||
|
Value Timespec
|
||||||
|
}
|
||||||
|
|
||||||
|
// ItimerVal mimics the following struct in <sys/time.h>
|
||||||
|
//
|
||||||
|
// struct itimerval {
|
||||||
|
// struct timeval it_interval; /* next value */
|
||||||
|
// struct timeval it_value; /* current value */
|
||||||
|
// };
|
||||||
|
//
|
||||||
|
// +marshal
|
||||||
|
type ItimerVal struct {
|
||||||
|
Interval Timeval
|
||||||
|
Value Timeval
|
||||||
|
}
|
||||||
|
|
||||||
|
// ClockT represents type clock_t.
|
||||||
|
//
|
||||||
|
// +marshal
|
||||||
|
type ClockT int64
|
||||||
|
|
||||||
|
// ClockTFromDuration converts time.Duration to clock_t.
|
||||||
|
func ClockTFromDuration(d time.Duration) ClockT {
|
||||||
|
return ClockT(d / ClockTick)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Tms represents struct tms, used by times(2).
|
||||||
|
//
|
||||||
|
// +marshal
|
||||||
|
type Tms struct {
|
||||||
|
UTime ClockT
|
||||||
|
STime ClockT
|
||||||
|
CUTime ClockT
|
||||||
|
CSTime ClockT
|
||||||
|
}
|
||||||
|
|
||||||
|
// TimerID represents type timer_t, which identifies a POSIX per-process
|
||||||
|
// interval timer.
|
||||||
|
//
|
||||||
|
// +marshal
|
||||||
|
type TimerID int32
|
||||||
|
|
||||||
|
// StatxTimestamp represents struct statx_timestamp.
|
||||||
|
//
|
||||||
|
// +marshal
|
||||||
|
type StatxTimestamp struct {
|
||||||
|
Sec int64
|
||||||
|
Nsec uint32
|
||||||
|
_ int32
|
||||||
|
}
|
||||||
|
|
||||||
|
// ToNsec returns the nanosecond representation.
|
||||||
|
func (sxts StatxTimestamp) ToNsec() int64 {
|
||||||
|
return int64(sxts.Sec)*1e9 + int64(sxts.Nsec)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ToNsecCapped returns the safe nanosecond representation.
|
||||||
|
func (sxts StatxTimestamp) ToNsecCapped() int64 {
|
||||||
|
if sxts.Sec > maxSecInDuration {
|
||||||
|
return math.MaxInt64
|
||||||
|
}
|
||||||
|
return sxts.ToNsec()
|
||||||
|
}
|
||||||
|
|
||||||
|
// NsecToStatxTimestamp translates nanoseconds to StatxTimestamp.
|
||||||
|
func NsecToStatxTimestamp(nsec int64) (ts StatxTimestamp) {
|
||||||
|
return StatxTimestamp{
|
||||||
|
Sec: nsec / 1e9,
|
||||||
|
Nsec: uint32(nsec % 1e9),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ToTime returns the Go time.Time representation.
|
||||||
|
func (sxts StatxTimestamp) ToTime() time.Time {
|
||||||
|
return time.Unix(sxts.Sec, int64(sxts.Nsec))
|
||||||
|
}
|
||||||
|
|
||||||
|
// Utime represents struct utimbuf used by utimes(2).
|
||||||
|
//
|
||||||
|
// +marshal
|
||||||
|
type Utime struct {
|
||||||
|
Actime int64
|
||||||
|
Modtime int64
|
||||||
|
}
|
||||||
23
pkg/abi/linux/timer.go
Normal file
23
pkg/abi/linux/timer.go
Normal file
|
|
@ -0,0 +1,23 @@
|
||||||
|
// Copyright 2018 The gVisor 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 linux
|
||||||
|
|
||||||
|
// itimer types for getitimer(2) and setitimer(2), from
|
||||||
|
// include/uapi/linux/time.h.
|
||||||
|
const (
|
||||||
|
ITIMER_REAL = 0
|
||||||
|
ITIMER_VIRTUAL = 1
|
||||||
|
ITIMER_PROF = 2
|
||||||
|
)
|
||||||
349
pkg/abi/linux/tty.go
Normal file
349
pkg/abi/linux/tty.go
Normal file
|
|
@ -0,0 +1,349 @@
|
||||||
|
// Copyright 2018 The gVisor 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 linux
|
||||||
|
|
||||||
|
const (
|
||||||
|
// NumControlCharacters is the number of control characters in Termios.
|
||||||
|
NumControlCharacters = 19
|
||||||
|
// disabledChar is used to indicate that a control character is
|
||||||
|
// disabled.
|
||||||
|
disabledChar = 0
|
||||||
|
)
|
||||||
|
|
||||||
|
// Winsize is struct winsize, defined in uapi/asm-generic/termios.h.
|
||||||
|
//
|
||||||
|
// +marshal
|
||||||
|
type Winsize struct {
|
||||||
|
Row uint16
|
||||||
|
Col uint16
|
||||||
|
Xpixel uint16
|
||||||
|
Ypixel uint16
|
||||||
|
}
|
||||||
|
|
||||||
|
// Termios is struct termios, defined in uapi/asm-generic/termbits.h.
|
||||||
|
//
|
||||||
|
// +marshal
|
||||||
|
type Termios struct {
|
||||||
|
InputFlags uint32
|
||||||
|
OutputFlags uint32
|
||||||
|
ControlFlags uint32
|
||||||
|
LocalFlags uint32
|
||||||
|
LineDiscipline uint8
|
||||||
|
ControlCharacters [NumControlCharacters]uint8
|
||||||
|
}
|
||||||
|
|
||||||
|
// KernelTermios is struct ktermios/struct termios2, defined in
|
||||||
|
// uapi/asm-generic/termbits.h.
|
||||||
|
//
|
||||||
|
// +stateify savable
|
||||||
|
type KernelTermios struct {
|
||||||
|
InputFlags uint32
|
||||||
|
OutputFlags uint32
|
||||||
|
ControlFlags uint32
|
||||||
|
LocalFlags uint32
|
||||||
|
LineDiscipline uint8
|
||||||
|
ControlCharacters [NumControlCharacters]uint8
|
||||||
|
InputSpeed uint32
|
||||||
|
OutputSpeed uint32
|
||||||
|
}
|
||||||
|
|
||||||
|
// IEnabled returns whether flag is enabled in termios input flags.
|
||||||
|
func (t *KernelTermios) IEnabled(flag uint32) bool {
|
||||||
|
return t.InputFlags&flag == flag
|
||||||
|
}
|
||||||
|
|
||||||
|
// OEnabled returns whether flag is enabled in termios output flags.
|
||||||
|
func (t *KernelTermios) OEnabled(flag uint32) bool {
|
||||||
|
return t.OutputFlags&flag == flag
|
||||||
|
}
|
||||||
|
|
||||||
|
// CEnabled returns whether flag is enabled in termios control flags.
|
||||||
|
func (t *KernelTermios) CEnabled(flag uint32) bool {
|
||||||
|
return t.ControlFlags&flag == flag
|
||||||
|
}
|
||||||
|
|
||||||
|
// LEnabled returns whether flag is enabled in termios local flags.
|
||||||
|
func (t *KernelTermios) LEnabled(flag uint32) bool {
|
||||||
|
return t.LocalFlags&flag == flag
|
||||||
|
}
|
||||||
|
|
||||||
|
// ToTermios copies fields that are shared with Termios into a new Termios
|
||||||
|
// struct.
|
||||||
|
func (t *KernelTermios) ToTermios() Termios {
|
||||||
|
return Termios{
|
||||||
|
InputFlags: t.InputFlags,
|
||||||
|
OutputFlags: t.OutputFlags,
|
||||||
|
ControlFlags: t.ControlFlags,
|
||||||
|
LocalFlags: t.LocalFlags,
|
||||||
|
LineDiscipline: t.LineDiscipline,
|
||||||
|
ControlCharacters: t.ControlCharacters,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// FromTermios copies fields that are shared with Termios into this
|
||||||
|
// KernelTermios struct.
|
||||||
|
func (t *KernelTermios) FromTermios(term Termios) {
|
||||||
|
t.InputFlags = term.InputFlags
|
||||||
|
t.OutputFlags = term.OutputFlags
|
||||||
|
t.ControlFlags = term.ControlFlags
|
||||||
|
t.LocalFlags = term.LocalFlags
|
||||||
|
t.LineDiscipline = term.LineDiscipline
|
||||||
|
t.ControlCharacters = term.ControlCharacters
|
||||||
|
}
|
||||||
|
|
||||||
|
// IsTerminating returns whether c is a line terminating character.
|
||||||
|
func (t *KernelTermios) IsTerminating(cBytes []byte) bool {
|
||||||
|
// All terminating characters are 1 byte.
|
||||||
|
if len(cBytes) != 1 {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
c := cBytes[0]
|
||||||
|
|
||||||
|
// Is this the user-set EOF character?
|
||||||
|
if t.IsEOF(c) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
switch c {
|
||||||
|
case disabledChar:
|
||||||
|
return false
|
||||||
|
case '\n', t.ControlCharacters[VEOL]:
|
||||||
|
return true
|
||||||
|
case t.ControlCharacters[VEOL2]:
|
||||||
|
return t.LEnabled(IEXTEN)
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
// IsEOF returns whether c is the EOF character.
|
||||||
|
func (t *KernelTermios) IsEOF(c byte) bool {
|
||||||
|
return c == t.ControlCharacters[VEOF] && t.ControlCharacters[VEOF] != disabledChar
|
||||||
|
}
|
||||||
|
|
||||||
|
// Input flags.
|
||||||
|
const (
|
||||||
|
IGNBRK = 0o000001
|
||||||
|
BRKINT = 0o000002
|
||||||
|
IGNPAR = 0o000004
|
||||||
|
PARMRK = 0o000010
|
||||||
|
INPCK = 0o000020
|
||||||
|
ISTRIP = 0o000040
|
||||||
|
INLCR = 0o000100
|
||||||
|
IGNCR = 0o000200
|
||||||
|
ICRNL = 0o000400
|
||||||
|
IUCLC = 0o001000
|
||||||
|
IXON = 0o002000
|
||||||
|
IXANY = 0o004000
|
||||||
|
IXOFF = 0o010000
|
||||||
|
IMAXBEL = 0o020000
|
||||||
|
IUTF8 = 0o040000
|
||||||
|
)
|
||||||
|
|
||||||
|
// Output flags.
|
||||||
|
const (
|
||||||
|
OPOST = 0o000001
|
||||||
|
OLCUC = 0o000002
|
||||||
|
ONLCR = 0o000004
|
||||||
|
OCRNL = 0o000010
|
||||||
|
ONOCR = 0o000020
|
||||||
|
ONLRET = 0o000040
|
||||||
|
OFILL = 0o000100
|
||||||
|
OFDEL = 0o000200
|
||||||
|
NLDLY = 0o000400
|
||||||
|
NL0 = 0o000000
|
||||||
|
NL1 = 0o000400
|
||||||
|
CRDLY = 0o003000
|
||||||
|
CR0 = 0o000000
|
||||||
|
CR1 = 0o001000
|
||||||
|
CR2 = 0o002000
|
||||||
|
CR3 = 0o003000
|
||||||
|
TABDLY = 0o014000
|
||||||
|
TAB0 = 0o000000
|
||||||
|
TAB1 = 0o004000
|
||||||
|
TAB2 = 0o010000
|
||||||
|
TAB3 = 0o014000
|
||||||
|
XTABS = 0o014000
|
||||||
|
BSDLY = 0o020000
|
||||||
|
BS0 = 0o000000
|
||||||
|
BS1 = 0o020000
|
||||||
|
VTDLY = 0o040000
|
||||||
|
VT0 = 0o000000
|
||||||
|
VT1 = 0o040000
|
||||||
|
FFDLY = 0o100000
|
||||||
|
FF0 = 0o000000
|
||||||
|
FF1 = 0o100000
|
||||||
|
)
|
||||||
|
|
||||||
|
// Control flags.
|
||||||
|
const (
|
||||||
|
CBAUD = 0o010017
|
||||||
|
B0 = 0o000000
|
||||||
|
B50 = 0o000001
|
||||||
|
B75 = 0o000002
|
||||||
|
B110 = 0o000003
|
||||||
|
B134 = 0o000004
|
||||||
|
B150 = 0o000005
|
||||||
|
B200 = 0o000006
|
||||||
|
B300 = 0o000007
|
||||||
|
B600 = 0o000010
|
||||||
|
B1200 = 0o000011
|
||||||
|
B1800 = 0o000012
|
||||||
|
B2400 = 0o000013
|
||||||
|
B4800 = 0o000014
|
||||||
|
B9600 = 0o000015
|
||||||
|
B19200 = 0o000016
|
||||||
|
B38400 = 0o000017
|
||||||
|
EXTA = B19200
|
||||||
|
EXTB = B38400
|
||||||
|
CSIZE = 0o000060
|
||||||
|
CS5 = 0o000000
|
||||||
|
CS6 = 0o000020
|
||||||
|
CS7 = 0o000040
|
||||||
|
CS8 = 0o000060
|
||||||
|
CSTOPB = 0o000100
|
||||||
|
CREAD = 0o000200
|
||||||
|
PARENB = 0o000400
|
||||||
|
PARODD = 0o001000
|
||||||
|
HUPCL = 0o002000
|
||||||
|
CLOCAL = 0o004000
|
||||||
|
CBAUDEX = 0o010000
|
||||||
|
BOTHER = 0o010000
|
||||||
|
B57600 = 0o010001
|
||||||
|
B115200 = 0o010002
|
||||||
|
B230400 = 0o010003
|
||||||
|
B460800 = 0o010004
|
||||||
|
B500000 = 0o010005
|
||||||
|
B576000 = 0o010006
|
||||||
|
B921600 = 0o010007
|
||||||
|
B1000000 = 0o010010
|
||||||
|
B1152000 = 0o010011
|
||||||
|
B1500000 = 0o010012
|
||||||
|
B2000000 = 0o010013
|
||||||
|
B2500000 = 0o010014
|
||||||
|
B3000000 = 0o010015
|
||||||
|
B3500000 = 0o010016
|
||||||
|
B4000000 = 0o010017
|
||||||
|
CIBAUD = 0o02003600000
|
||||||
|
CMSPAR = 0o10000000000
|
||||||
|
CRTSCTS = 0o20000000000
|
||||||
|
|
||||||
|
// IBSHIFT is the shift from CBAUD to CIBAUD.
|
||||||
|
IBSHIFT = 16
|
||||||
|
)
|
||||||
|
|
||||||
|
// Local flags.
|
||||||
|
const (
|
||||||
|
ISIG = 0o000001
|
||||||
|
ICANON = 0o000002
|
||||||
|
XCASE = 0o000004
|
||||||
|
ECHO = 0o000010
|
||||||
|
ECHOE = 0o000020
|
||||||
|
ECHOK = 0o000040
|
||||||
|
ECHONL = 0o000100
|
||||||
|
NOFLSH = 0o000200
|
||||||
|
TOSTOP = 0o000400
|
||||||
|
ECHOCTL = 0o001000
|
||||||
|
ECHOPRT = 0o002000
|
||||||
|
ECHOKE = 0o004000
|
||||||
|
FLUSHO = 0o010000
|
||||||
|
PENDIN = 0o040000
|
||||||
|
IEXTEN = 0o100000
|
||||||
|
EXTPROC = 0o200000
|
||||||
|
)
|
||||||
|
|
||||||
|
// Control Character indices.
|
||||||
|
const (
|
||||||
|
VINTR = 0
|
||||||
|
VQUIT = 1
|
||||||
|
VERASE = 2
|
||||||
|
VKILL = 3
|
||||||
|
VEOF = 4
|
||||||
|
VTIME = 5
|
||||||
|
VMIN = 6
|
||||||
|
VSWTC = 7
|
||||||
|
VSTART = 8
|
||||||
|
VSTOP = 9
|
||||||
|
VSUSP = 10
|
||||||
|
VEOL = 11
|
||||||
|
VREPRINT = 12
|
||||||
|
VDISCARD = 13
|
||||||
|
VWERASE = 14
|
||||||
|
VLNEXT = 15
|
||||||
|
VEOL2 = 16
|
||||||
|
)
|
||||||
|
|
||||||
|
// ControlCharacter returns the termios-style control character for the passed
|
||||||
|
// character.
|
||||||
|
//
|
||||||
|
// e.g., for Ctrl-C, i.e., ^C, call ControlCharacter('C').
|
||||||
|
//
|
||||||
|
// Standard control characters are ASCII bytes 0 through 31.
|
||||||
|
func ControlCharacter(c byte) uint8 {
|
||||||
|
// A is 1, B is 2, etc.
|
||||||
|
return uint8(c - 'A' + 1)
|
||||||
|
}
|
||||||
|
|
||||||
|
// DefaultControlCharacters is the default set of Termios control characters.
|
||||||
|
var DefaultControlCharacters = [NumControlCharacters]uint8{
|
||||||
|
ControlCharacter('C'), // VINTR = ^C
|
||||||
|
ControlCharacter('\\'), // VQUIT = ^\
|
||||||
|
'\x7f', // VERASE = DEL
|
||||||
|
ControlCharacter('U'), // VKILL = ^U
|
||||||
|
ControlCharacter('D'), // VEOF = ^D
|
||||||
|
0, // VTIME
|
||||||
|
1, // VMIN
|
||||||
|
0, // VSWTC
|
||||||
|
ControlCharacter('Q'), // VSTART = ^Q
|
||||||
|
ControlCharacter('S'), // VSTOP = ^S
|
||||||
|
ControlCharacter('Z'), // VSUSP = ^Z
|
||||||
|
0, // VEOL
|
||||||
|
ControlCharacter('R'), // VREPRINT = ^R
|
||||||
|
ControlCharacter('O'), // VDISCARD = ^O
|
||||||
|
ControlCharacter('W'), // VWERASE = ^W
|
||||||
|
ControlCharacter('V'), // VLNEXT = ^V
|
||||||
|
0, // VEOL2
|
||||||
|
}
|
||||||
|
|
||||||
|
// MasterTermios is the terminal configuration of the master end of a Unix98
|
||||||
|
// pseudoterminal.
|
||||||
|
var MasterTermios = KernelTermios{
|
||||||
|
ControlFlags: B38400 | CS8 | CREAD,
|
||||||
|
ControlCharacters: DefaultControlCharacters,
|
||||||
|
InputSpeed: 38400,
|
||||||
|
OutputSpeed: 38400,
|
||||||
|
}
|
||||||
|
|
||||||
|
// DefaultReplicaTermios is the default terminal configuration of the replica
|
||||||
|
// end of a Unix98 pseudoterminal.
|
||||||
|
var DefaultReplicaTermios = KernelTermios{
|
||||||
|
InputFlags: ICRNL | IXON,
|
||||||
|
OutputFlags: OPOST | ONLCR,
|
||||||
|
ControlFlags: B38400 | CS8 | CREAD,
|
||||||
|
LocalFlags: ISIG | ICANON | ECHO | ECHOE | ECHOK | ECHOCTL | ECHOKE | IEXTEN,
|
||||||
|
ControlCharacters: DefaultControlCharacters,
|
||||||
|
InputSpeed: 38400,
|
||||||
|
OutputSpeed: 38400,
|
||||||
|
}
|
||||||
|
|
||||||
|
// WindowSize corresponds to struct winsize defined in
|
||||||
|
// include/uapi/asm-generic/termios.h.
|
||||||
|
//
|
||||||
|
// +stateify savable
|
||||||
|
// +marshal
|
||||||
|
type WindowSize struct {
|
||||||
|
Rows uint16
|
||||||
|
Cols uint16
|
||||||
|
_ [4]byte // Padding for 2 unused shorts.
|
||||||
|
}
|
||||||
18
pkg/abi/linux/uio.go
Normal file
18
pkg/abi/linux/uio.go
Normal file
|
|
@ -0,0 +1,18 @@
|
||||||
|
// Copyright 2018 The gVisor 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 linux
|
||||||
|
|
||||||
|
// UIO_MAXIOV is the maximum number of struct iovecs in a struct iovec array.
|
||||||
|
const UIO_MAXIOV = 1024
|
||||||
51
pkg/abi/linux/utsname.go
Normal file
51
pkg/abi/linux/utsname.go
Normal file
|
|
@ -0,0 +1,51 @@
|
||||||
|
// Copyright 2018 The gVisor 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 linux
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"fmt"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
// UTSLen is the maximum length of strings contained in fields of
|
||||||
|
// UtsName.
|
||||||
|
UTSLen = 64
|
||||||
|
)
|
||||||
|
|
||||||
|
// UtsName represents struct utsname, the struct returned by uname(2).
|
||||||
|
//
|
||||||
|
// +marshal
|
||||||
|
type UtsName struct {
|
||||||
|
Sysname [UTSLen + 1]byte
|
||||||
|
Nodename [UTSLen + 1]byte
|
||||||
|
Release [UTSLen + 1]byte
|
||||||
|
Version [UTSLen + 1]byte
|
||||||
|
Machine [UTSLen + 1]byte
|
||||||
|
Domainname [UTSLen + 1]byte
|
||||||
|
}
|
||||||
|
|
||||||
|
// utsNameString converts a UtsName entry to a string without NULs.
|
||||||
|
func utsNameString(s [UTSLen + 1]byte) string {
|
||||||
|
// The NUL bytes will remain even in a cast to string. We must
|
||||||
|
// explicitly strip them.
|
||||||
|
return string(bytes.TrimRight(s[:], "\x00"))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (u UtsName) String() string {
|
||||||
|
return fmt.Sprintf("{Sysname: %s, Nodename: %s, Release: %s, Version: %s, Machine: %s, Domainname: %s}",
|
||||||
|
utsNameString(u.Sysname), utsNameString(u.Nodename), utsNameString(u.Release),
|
||||||
|
utsNameString(u.Version), utsNameString(u.Machine), utsNameString(u.Domainname))
|
||||||
|
}
|
||||||
215
pkg/abi/linux/vfio.go
Normal file
215
pkg/abi/linux/vfio.go
Normal file
|
|
@ -0,0 +1,215 @@
|
||||||
|
// Copyright 2024 The gVisor 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.
|
||||||
|
|
||||||
|
// The package implements VFIOuserspace driver interface.
|
||||||
|
|
||||||
|
package linux
|
||||||
|
|
||||||
|
// For IOCTLs requests from include/uapi/linux/vfio.h.
|
||||||
|
const (
|
||||||
|
VFIO_TYPE = ';'
|
||||||
|
VFIO_BASE = 100
|
||||||
|
|
||||||
|
// VFIO extensions.
|
||||||
|
VFIO_TYPE1_IOMMU = 1
|
||||||
|
VFIO_SPAPR_TCE_IOMMU = 2
|
||||||
|
VFIO_TYPE1v2_IOMMU = 3
|
||||||
|
)
|
||||||
|
|
||||||
|
// VFIO device info flags.
|
||||||
|
const (
|
||||||
|
// Device supports reset.
|
||||||
|
VFIO_DEVICE_FLAGS_RESET = 1 << iota
|
||||||
|
// VFIO-pci device.
|
||||||
|
VFIO_DEVICE_FLAGS_PCI
|
||||||
|
// VFIO-platform device.
|
||||||
|
VFIO_DEVICE_FLAGS_PLATFORM
|
||||||
|
// VFIO-amba device.
|
||||||
|
VFIO_DEVICE_FLAGS_AMBA
|
||||||
|
// VFIO-ccw device.
|
||||||
|
VFIO_DEVICE_FLAGS_CCW
|
||||||
|
// VFIO-ap device.
|
||||||
|
VFIO_DEVICE_FLAGS_AP
|
||||||
|
// VFIO-fsl-mc device.
|
||||||
|
VFIO_DEVICE_FLAGS_FSL_MC
|
||||||
|
// Info supports caps.
|
||||||
|
VFIO_DEVICE_FLAGS_CAPS
|
||||||
|
// VFIO-cdx device.
|
||||||
|
VFIO_DEVICE_FLAGS_CDX
|
||||||
|
)
|
||||||
|
|
||||||
|
// VFIO region info flags.
|
||||||
|
const (
|
||||||
|
// Region supports read.
|
||||||
|
VFIO_REGION_INFO_FLAG_READ = 1 << iota
|
||||||
|
// Region supports write.
|
||||||
|
VFIO_REGION_INFO_FLAG_WRITE
|
||||||
|
// Region supports mmap.
|
||||||
|
VFIO_REGION_INFO_FLAG_MMAP
|
||||||
|
// Info supports caps.
|
||||||
|
VFIO_REGION_INFO_FLAG_CAPS
|
||||||
|
)
|
||||||
|
|
||||||
|
// VFIOIrqInfo flags.
|
||||||
|
const (
|
||||||
|
VFIO_IRQ_INFO_EVENTFD = 1 << iota
|
||||||
|
VFIO_IRQ_INFO_MASKABLE
|
||||||
|
VFIO_IRQ_INFO_AUTOMASKED
|
||||||
|
VFIO_IRQ_INFO_NORESIZE
|
||||||
|
)
|
||||||
|
|
||||||
|
// VFIOIrqSet flags.
|
||||||
|
const (
|
||||||
|
VFIO_IRQ_SET_DATA_NONE = 1 << iota
|
||||||
|
VFIO_IRQ_SET_DATA_BOOL
|
||||||
|
VFIO_IRQ_SET_DATA_EVENTFD
|
||||||
|
VFIO_IRQ_SET_ACTION_MASK
|
||||||
|
VFIO_IRQ_SET_ACTION_UNMASK
|
||||||
|
VFIO_IRQ_SET_ACTION_TRIGGER
|
||||||
|
|
||||||
|
VFIO_IRQ_SET_DATA_TYPE_MASK = VFIO_IRQ_SET_DATA_NONE |
|
||||||
|
VFIO_IRQ_SET_DATA_BOOL |
|
||||||
|
VFIO_IRQ_SET_DATA_EVENTFD
|
||||||
|
VFIO_IRQ_SET_ACTION_TYPE_MASK = VFIO_IRQ_SET_ACTION_MASK |
|
||||||
|
VFIO_IRQ_SET_ACTION_UNMASK |
|
||||||
|
VFIO_IRQ_SET_ACTION_TRIGGER
|
||||||
|
)
|
||||||
|
|
||||||
|
// VFIOIrqSet index.
|
||||||
|
const (
|
||||||
|
VFIO_PCI_INTX_IRQ_INDEX = iota
|
||||||
|
VFIO_PCI_MSI_IRQ_INDEX
|
||||||
|
VFIO_PCI_MSIX_IRQ_INDEX
|
||||||
|
VFIO_PCI_ERR_IRQ_INDEX
|
||||||
|
VFIO_PCI_REQ_IRQ_INDEX
|
||||||
|
VFIO_PCI_NUM_IRQS
|
||||||
|
)
|
||||||
|
|
||||||
|
// VFIOIommuType1DmaMap flags.
|
||||||
|
const (
|
||||||
|
// Readable from device.
|
||||||
|
VFIO_DMA_MAP_FLAG_READ = 1 << iota
|
||||||
|
// Writable from device.
|
||||||
|
VFIO_DMA_MAP_FLAG_WRITE
|
||||||
|
// Update the device's virtual address.
|
||||||
|
VFIO_DMA_MAP_FLAG_VADDR
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
VFIO_DMA_UNMAP_FLAG_GET_DIRTY_BITMAP = 1
|
||||||
|
)
|
||||||
|
|
||||||
|
// IOCTLs for VFIO file descriptor from include/uapi/linux/vfio.h.
|
||||||
|
var (
|
||||||
|
VFIO_CHECK_EXTENSION = IO(VFIO_TYPE, VFIO_BASE+1)
|
||||||
|
VFIO_SET_IOMMU = IO(VFIO_TYPE, VFIO_BASE+2)
|
||||||
|
VFIO_GROUP_SET_CONTAINER = IO(VFIO_TYPE, VFIO_BASE+4)
|
||||||
|
VFIO_GROUP_UNSET_CONTAINER = IO(VFIO_TYPE, VFIO_BASE+5)
|
||||||
|
VFIO_GROUP_GET_DEVICE_FD = IO(VFIO_TYPE, VFIO_BASE+6)
|
||||||
|
VFIO_DEVICE_GET_INFO = IO(VFIO_TYPE, VFIO_BASE+7)
|
||||||
|
VFIO_DEVICE_GET_REGION_INFO = IO(VFIO_TYPE, VFIO_BASE+8)
|
||||||
|
VFIO_DEVICE_GET_IRQ_INFO = IO(VFIO_TYPE, VFIO_BASE+9)
|
||||||
|
VFIO_DEVICE_SET_IRQS = IO(VFIO_TYPE, VFIO_BASE+10)
|
||||||
|
VFIO_DEVICE_RESET = IO(VFIO_TYPE, VFIO_BASE+11)
|
||||||
|
VFIO_IOMMU_MAP_DMA = IO(VFIO_TYPE, VFIO_BASE+13)
|
||||||
|
VFIO_IOMMU_UNMAP_DMA = IO(VFIO_TYPE, VFIO_BASE+14)
|
||||||
|
)
|
||||||
|
|
||||||
|
// VFIODeviceInfo is analogous to vfio_device_info
|
||||||
|
// from include/uapi/linux/vfio.h.
|
||||||
|
//
|
||||||
|
// +marshal
|
||||||
|
type VFIODeviceInfo struct {
|
||||||
|
Argsz uint32
|
||||||
|
Flags uint32
|
||||||
|
// The total amount of regions.
|
||||||
|
NumRegions uint32
|
||||||
|
// The maximum number of IRQ.
|
||||||
|
NumIrqs uint32
|
||||||
|
// Offset within info struct of first cap.
|
||||||
|
CapOffset uint32
|
||||||
|
pad uint32
|
||||||
|
}
|
||||||
|
|
||||||
|
// VFIORegionInfo is analogous to vfio_region_info
|
||||||
|
// from include/uapi/linux/vfio.h.
|
||||||
|
//
|
||||||
|
// +marshal
|
||||||
|
type VFIORegionInfo struct {
|
||||||
|
Argsz uint32
|
||||||
|
Flags uint32
|
||||||
|
Index uint32
|
||||||
|
// Offset within info struct of first cap.
|
||||||
|
capOffset uint32
|
||||||
|
// Region size in bytes.
|
||||||
|
Size uint64
|
||||||
|
// Region offset from start of device fd.
|
||||||
|
Offset uint64
|
||||||
|
}
|
||||||
|
|
||||||
|
// VFIOIrqInfo is analogous to vfio_irq_info
|
||||||
|
// from include/uapi/linux/vfio.h.
|
||||||
|
//
|
||||||
|
// +marshal
|
||||||
|
type VFIOIrqInfo struct {
|
||||||
|
Argsz uint32
|
||||||
|
Flags uint32
|
||||||
|
Index uint32
|
||||||
|
Count uint32
|
||||||
|
}
|
||||||
|
|
||||||
|
// VFIOIrqSet is analogous to vfio_irq_set
|
||||||
|
// from include/uapi/linux/vfio.h.
|
||||||
|
// The last field `data` from vfio_irq_set is omitted which is an
|
||||||
|
// flexible array member. It will be handled separately.
|
||||||
|
//
|
||||||
|
// +marshal
|
||||||
|
type VFIOIrqSet struct {
|
||||||
|
Argsz uint32
|
||||||
|
Flags uint32
|
||||||
|
Index uint32
|
||||||
|
Start uint32
|
||||||
|
Count uint32
|
||||||
|
}
|
||||||
|
|
||||||
|
// VFIOIommuType1DmaMap is analogous to vfio_iommu_type1_dma_map
|
||||||
|
// from include/uapi/linux/vfio.h.
|
||||||
|
//
|
||||||
|
// +marshal
|
||||||
|
type VFIOIommuType1DmaMap struct {
|
||||||
|
Argsz uint32
|
||||||
|
Flags uint32
|
||||||
|
// Process virtual address.
|
||||||
|
Vaddr uint64
|
||||||
|
// IO virtual address.
|
||||||
|
IOVa uint64
|
||||||
|
// Size of mapping in bytes.
|
||||||
|
Size uint64
|
||||||
|
}
|
||||||
|
|
||||||
|
// VFIOIommuType1DmaUnmap is analogous to vfio_iommu_type1_dma_unmap
|
||||||
|
// from include/uapi/linux/vfio.h.
|
||||||
|
//
|
||||||
|
// +marshal
|
||||||
|
type VFIOIommuType1DmaUnmap struct {
|
||||||
|
Argsz uint32
|
||||||
|
Flags uint32
|
||||||
|
// IO virtual address.
|
||||||
|
IOVa uint64
|
||||||
|
// Size of mapping in bytes.
|
||||||
|
Size uint64
|
||||||
|
// The `data` field from vfio_iommu_type1_dma_unmap is omitted. The
|
||||||
|
// field is a flexible array member, and is needed only if the flag
|
||||||
|
// VFIO_DMA_UNMAP_FLAG_GET_DIRTY_BITMAP is enabled.
|
||||||
|
}
|
||||||
22
pkg/abi/linux/vfio_unsafe.go
Normal file
22
pkg/abi/linux/vfio_unsafe.go
Normal file
|
|
@ -0,0 +1,22 @@
|
||||||
|
// Copyright 2024 The gVisor 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 linux
|
||||||
|
|
||||||
|
import "unsafe"
|
||||||
|
|
||||||
|
// Size returns the number of bytes for a VFIOIrqSet object.
|
||||||
|
func (vfioIrqSet VFIOIrqSet) Size() uint64 {
|
||||||
|
return uint64(unsafe.Sizeof(vfioIrqSet))
|
||||||
|
}
|
||||||
161
pkg/abi/linux/wait.go
Normal file
161
pkg/abi/linux/wait.go
Normal file
|
|
@ -0,0 +1,161 @@
|
||||||
|
// Copyright 2019 The gVisor 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 linux
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Options for waitpid(2), wait4(2), and/or waitid(2), from
|
||||||
|
// include/uapi/linux/wait.h.
|
||||||
|
const (
|
||||||
|
WNOHANG = 0x00000001
|
||||||
|
WUNTRACED = 0x00000002
|
||||||
|
WSTOPPED = WUNTRACED
|
||||||
|
WEXITED = 0x00000004
|
||||||
|
WCONTINUED = 0x00000008
|
||||||
|
WNOWAIT = 0x01000000
|
||||||
|
WNOTHREAD = 0x20000000
|
||||||
|
WALL = 0x40000000
|
||||||
|
WCLONE = 0x80000000
|
||||||
|
)
|
||||||
|
|
||||||
|
// ID types for waitid(2), from include/uapi/linux/wait.h.
|
||||||
|
const (
|
||||||
|
P_ALL = 0x0
|
||||||
|
P_PID = 0x1
|
||||||
|
P_PGID = 0x2
|
||||||
|
)
|
||||||
|
|
||||||
|
// WaitStatus represents a thread status, as returned by the wait* family of
|
||||||
|
// syscalls.
|
||||||
|
type WaitStatus uint32
|
||||||
|
|
||||||
|
// WaitStatusExit returns a WaitStatus representing the given exit status.
|
||||||
|
func WaitStatusExit(status int32) WaitStatus {
|
||||||
|
return WaitStatus(uint32(status) << 8)
|
||||||
|
}
|
||||||
|
|
||||||
|
// WaitStatusTerminationSignal returns a WaitStatus representing termination by
|
||||||
|
// the given signal.
|
||||||
|
func WaitStatusTerminationSignal(sig Signal) WaitStatus {
|
||||||
|
return WaitStatus(uint32(sig))
|
||||||
|
}
|
||||||
|
|
||||||
|
// WaitStatusStopped returns a WaitStatus representing stoppage by the given
|
||||||
|
// signal or ptrace trap code.
|
||||||
|
func WaitStatusStopped(code uint32) WaitStatus {
|
||||||
|
return WaitStatus(code<<8 | 0x7f)
|
||||||
|
}
|
||||||
|
|
||||||
|
// WaitStatusContinued returns a WaitStatus representing continuation by
|
||||||
|
// SIGCONT.
|
||||||
|
func WaitStatusContinued() WaitStatus {
|
||||||
|
return WaitStatus(0xffff)
|
||||||
|
}
|
||||||
|
|
||||||
|
// WithCoreDump returns a copy of ws that indicates that a core dump was
|
||||||
|
// generated.
|
||||||
|
//
|
||||||
|
// Preconditions: ws.Signaled().
|
||||||
|
func (ws WaitStatus) WithCoreDump() WaitStatus {
|
||||||
|
return ws | 0x80
|
||||||
|
}
|
||||||
|
|
||||||
|
// Exited returns true if ws represents an exit status, consistent with
|
||||||
|
// WIFEXITED.
|
||||||
|
func (ws WaitStatus) Exited() bool {
|
||||||
|
return ws&0x7f == 0
|
||||||
|
}
|
||||||
|
|
||||||
|
// Signaled returns true if ws represents a termination by signal, consistent
|
||||||
|
// with WIFSIGNALED.
|
||||||
|
func (ws WaitStatus) Signaled() bool {
|
||||||
|
// ws&0x7f != 0 (exited) and ws&0x7f != 0x7f (stopped or continued)
|
||||||
|
return ((ws&0x7f)+1)>>1 != 0
|
||||||
|
}
|
||||||
|
|
||||||
|
// CoreDumped returns true if ws indicates that a core dump was produced,
|
||||||
|
// consistent with WCOREDUMP.
|
||||||
|
//
|
||||||
|
// Preconditions: ws.Signaled().
|
||||||
|
func (ws WaitStatus) CoreDumped() bool {
|
||||||
|
return ws&0x80 != 0
|
||||||
|
}
|
||||||
|
|
||||||
|
// Stopped returns true if ws represents a stoppage, consistent with
|
||||||
|
// WIFSTOPPED.
|
||||||
|
func (ws WaitStatus) Stopped() bool {
|
||||||
|
return ws&0xff == 0x7f
|
||||||
|
}
|
||||||
|
|
||||||
|
// Continued returns true if ws represents a continuation by SIGCONT,
|
||||||
|
// consistent with WIFCONTINUED.
|
||||||
|
func (ws WaitStatus) Continued() bool {
|
||||||
|
return ws == 0xffff
|
||||||
|
}
|
||||||
|
|
||||||
|
// ExitStatus returns the lower 8 bits of the exit status represented by ws,
|
||||||
|
// consistent with WEXITSTATUS.
|
||||||
|
//
|
||||||
|
// Preconditions: ws.Exited().
|
||||||
|
func (ws WaitStatus) ExitStatus() uint32 {
|
||||||
|
return uint32((ws & 0xff00) >> 8)
|
||||||
|
}
|
||||||
|
|
||||||
|
// TerminationSignal returns the termination signal represented by ws,
|
||||||
|
// consistent with WTERMSIG.
|
||||||
|
//
|
||||||
|
// Preconditions: ws.Signaled().
|
||||||
|
func (ws WaitStatus) TerminationSignal() Signal {
|
||||||
|
return Signal(ws & 0x7f)
|
||||||
|
}
|
||||||
|
|
||||||
|
// StopSignal returns the stop signal represented by ws, consistent with
|
||||||
|
// WSTOPSIG.
|
||||||
|
//
|
||||||
|
// Preconditions: ws.Stopped().
|
||||||
|
func (ws WaitStatus) StopSignal() Signal {
|
||||||
|
return Signal((ws & 0xff00) >> 8)
|
||||||
|
}
|
||||||
|
|
||||||
|
// PtraceEvent returns the PTRACE_EVENT_* field in ws.
|
||||||
|
//
|
||||||
|
// Preconditions: ws.Stopped().
|
||||||
|
func (ws WaitStatus) PtraceEvent() uint32 {
|
||||||
|
return uint32(ws >> 16)
|
||||||
|
}
|
||||||
|
|
||||||
|
// String implements fmt.Stringer.String.
|
||||||
|
func (ws WaitStatus) String() string {
|
||||||
|
switch {
|
||||||
|
case ws.Exited():
|
||||||
|
return fmt.Sprintf("exit status %d", ws.ExitStatus())
|
||||||
|
case ws.Signaled():
|
||||||
|
if ws.CoreDumped() {
|
||||||
|
return fmt.Sprintf("killed by signal %d (core dumped)", ws.TerminationSignal())
|
||||||
|
}
|
||||||
|
return fmt.Sprintf("killed by signal %d", ws.TerminationSignal())
|
||||||
|
case ws.Stopped():
|
||||||
|
if ev := ws.PtraceEvent(); ev != 0 {
|
||||||
|
return fmt.Sprintf("stopped by signal %d (PTRACE_EVENT %d)", ws.StopSignal(), ev)
|
||||||
|
}
|
||||||
|
return fmt.Sprintf("stopped by signal %d", ws.StopSignal())
|
||||||
|
case ws.Continued():
|
||||||
|
return "continued"
|
||||||
|
default:
|
||||||
|
return fmt.Sprintf("unknown status %#x", uint32(ws))
|
||||||
|
}
|
||||||
|
}
|
||||||
39
pkg/abi/linux/xattr.go
Normal file
39
pkg/abi/linux/xattr.go
Normal file
|
|
@ -0,0 +1,39 @@
|
||||||
|
// Copyright 2019 The gVisor 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 linux
|
||||||
|
|
||||||
|
// Constants for extended attributes.
|
||||||
|
const (
|
||||||
|
XATTR_NAME_MAX = 255
|
||||||
|
XATTR_SIZE_MAX = 65536
|
||||||
|
XATTR_LIST_MAX = 65536
|
||||||
|
|
||||||
|
XATTR_CREATE = 1
|
||||||
|
XATTR_REPLACE = 2
|
||||||
|
|
||||||
|
XATTR_SECURITY_PREFIX = "security."
|
||||||
|
XATTR_SECURITY_PREFIX_LEN = len(XATTR_SECURITY_PREFIX)
|
||||||
|
|
||||||
|
XATTR_SECURITY_CAPABILITY = XATTR_SECURITY_PREFIX + "capability"
|
||||||
|
|
||||||
|
XATTR_SYSTEM_PREFIX = "system."
|
||||||
|
XATTR_SYSTEM_PREFIX_LEN = len(XATTR_SYSTEM_PREFIX)
|
||||||
|
|
||||||
|
XATTR_TRUSTED_PREFIX = "trusted."
|
||||||
|
XATTR_TRUSTED_PREFIX_LEN = len(XATTR_TRUSTED_PREFIX)
|
||||||
|
|
||||||
|
XATTR_USER_PREFIX = "user."
|
||||||
|
XATTR_USER_PREFIX_LEN = len(XATTR_USER_PREFIX)
|
||||||
|
)
|
||||||
590
pkg/abi/nvgpu/classes.go
Normal file
590
pkg/abi/nvgpu/classes.go
Normal file
|
|
@ -0,0 +1,590 @@
|
||||||
|
// Copyright 2023 The gVisor 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 nvgpu
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
)
|
||||||
|
|
||||||
|
// ClassID is a client class ID, in the sense of
|
||||||
|
// src/nvidia/src/kernel/rmapi/resource_desc.h:RS_RESOURCE_DESC::externalClassID.
|
||||||
|
//
|
||||||
|
// +marshal
|
||||||
|
type ClassID uint32
|
||||||
|
|
||||||
|
// String implements fmt.Stringer.String.
|
||||||
|
func (id ClassID) String() string {
|
||||||
|
// Include leading zeroes for easier searchability, both here and in
|
||||||
|
// g_allclasses.h.
|
||||||
|
return fmt.Sprintf("0x%08x", uint32(id))
|
||||||
|
}
|
||||||
|
|
||||||
|
// IsRootClient returns true if the given class ID is a root client class.
|
||||||
|
func (id ClassID) IsRootClient() bool {
|
||||||
|
switch id {
|
||||||
|
case NV01_ROOT, NV01_ROOT_NON_PRIV, NV01_ROOT_CLIENT:
|
||||||
|
return true
|
||||||
|
default:
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Class IDs, from src/nvidia/generated/g_allclasses.h.
|
||||||
|
const (
|
||||||
|
NV01_ROOT = 0x00000000
|
||||||
|
NV01_ROOT_NON_PRIV = 0x00000001
|
||||||
|
NV01_CONTEXT_DMA = 0x00000002
|
||||||
|
NV01_EVENT = 0x00000005
|
||||||
|
NV01_MEMORY_SYSTEM = 0x0000003e
|
||||||
|
NV01_MEMORY_LOCAL_PRIVILEGED = 0x0000003f
|
||||||
|
NV01_MEMORY_LOCAL_USER = 0x00000040
|
||||||
|
NV01_ROOT_CLIENT = 0x00000041
|
||||||
|
NV_MEMORY_EXTENDED_USER = 0x00000042
|
||||||
|
NV01_MEMORY_VIRTUAL = 0x00000070
|
||||||
|
NV01_MEMORY_SYSTEM_OS_DESCRIPTOR = 0x00000071
|
||||||
|
NV01_EVENT_OS_EVENT = 0x00000079
|
||||||
|
NV01_DEVICE_0 = 0x00000080
|
||||||
|
NV_SEMAPHORE_SURFACE = 0x000000da
|
||||||
|
RM_USER_SHARED_DATA = 0x000000de
|
||||||
|
NV_MEMORY_FABRIC = 0x000000f8
|
||||||
|
NV_MEMORY_MULTICAST_FABRIC = 0x000000fd
|
||||||
|
NV_MEMORY_MAPPER = 0x000000fe
|
||||||
|
NV20_SUBDEVICE_0 = 0x00002080
|
||||||
|
NV2081_BINAPI = 0x00002081
|
||||||
|
NV50_P2P = 0x0000503b
|
||||||
|
NV50_THIRD_PARTY_P2P = 0x0000503c
|
||||||
|
NV50_MEMORY_VIRTUAL = 0x000050a0
|
||||||
|
GT200_DEBUGGER = 0x000083de
|
||||||
|
FERMI_TWOD_A = 0x0000902d
|
||||||
|
FERMI_CONTEXT_SHARE_A = 0x00009067
|
||||||
|
GF100_DISP_SW = 0x00009072
|
||||||
|
GF100_ZBC_CLEAR = 0x00009096
|
||||||
|
GF100_PROFILER = 0x000090cc
|
||||||
|
GF100_SUBDEVICE_MASTER = 0x000090e6
|
||||||
|
FERMI_VASPACE_A = 0x000090f1
|
||||||
|
KEPLER_CHANNEL_GROUP_A = 0x0000a06c
|
||||||
|
NVENC_SW_SESSION = 0x0000a0bc
|
||||||
|
KEPLER_INLINE_TO_MEMORY_B = 0x0000a140
|
||||||
|
VOLTA_USERMODE_A = 0x0000c361
|
||||||
|
TURING_USERMODE_A = 0x0000c461
|
||||||
|
TURING_CHANNEL_GPFIFO_A = 0x0000c46f
|
||||||
|
NVB8B0_VIDEO_DECODER = 0x0000b8b0 // Hopper
|
||||||
|
NVC4B0_VIDEO_DECODER = 0x0000c4b0 // Turing
|
||||||
|
NVC6B0_VIDEO_DECODER = 0x0000c6b0 // Ampere
|
||||||
|
NVC7B0_VIDEO_DECODER = 0x0000c7b0 // Ampere
|
||||||
|
NVC9B0_VIDEO_DECODER = 0x0000c9b0 // Ada
|
||||||
|
NVCDB0_VIDEO_DECODER = 0x0000cdb0 // Blackwell
|
||||||
|
NVC4B7_VIDEO_ENCODER = 0x0000c4b7
|
||||||
|
NVC7B7_VIDEO_ENCODER = 0x0000c7b7
|
||||||
|
NVC9B7_VIDEO_ENCODER = 0x0000c9b7
|
||||||
|
AMPERE_CHANNEL_GPFIFO_A = 0x0000c56f
|
||||||
|
TURING_A = 0x0000c597
|
||||||
|
TURING_DMA_COPY_A = 0x0000c5b5
|
||||||
|
TURING_COMPUTE_A = 0x0000c5c0
|
||||||
|
HOPPER_USERMODE_A = 0x0000c661
|
||||||
|
BLACKWELL_USERMODE_A = 0x0000c761
|
||||||
|
AMPERE_A = 0x0000c697
|
||||||
|
AMPERE_DMA_COPY_A = 0x0000c6b5
|
||||||
|
AMPERE_COMPUTE_A = 0x0000c6c0
|
||||||
|
AMPERE_DMA_COPY_B = 0x0000c7b5
|
||||||
|
AMPERE_COMPUTE_B = 0x0000c7c0
|
||||||
|
HOPPER_CHANNEL_GPFIFO_A = 0x0000c86f
|
||||||
|
HOPPER_DMA_COPY_A = 0x0000c8b5
|
||||||
|
BLACKWELL_CHANNEL_GPFIFO_A = 0x0000c96f
|
||||||
|
BLACKWELL_DMA_COPY_A = 0x0000c9b5
|
||||||
|
BLACKWELL_CHANNEL_GPFIFO_B = 0x0000ca6f
|
||||||
|
BLACKWELL_DMA_COPY_B = 0x0000cab5
|
||||||
|
ADA_A = 0x0000c997
|
||||||
|
ADA_COMPUTE_A = 0x0000c9c0
|
||||||
|
NV_CONFIDENTIAL_COMPUTE = 0x0000cb33
|
||||||
|
HOPPER_A = 0x0000cb97
|
||||||
|
HOPPER_SEC2_WORK_LAUNCH_A = 0x0000cba2
|
||||||
|
HOPPER_COMPUTE_A = 0x0000cbc0
|
||||||
|
BLACKWELL_INLINE_TO_MEMORY_A = 0x0000cd40
|
||||||
|
BLACKWELL_A = 0x0000cd97
|
||||||
|
BLACKWELL_COMPUTE_A = 0x0000cdc0
|
||||||
|
BLACKWELL_B = 0x0000ce97
|
||||||
|
BLACKWELL_COMPUTE_B = 0x0000cec0
|
||||||
|
)
|
||||||
|
|
||||||
|
// From src/common/sdk/nvidia/inc/class/cl0000.h:
|
||||||
|
const (
|
||||||
|
NV01_NULL_OBJECT = 0x0
|
||||||
|
)
|
||||||
|
|
||||||
|
// NV2081_ALLOC_PARAMETERS is the alloc params type for NV2081_BINAPI, from
|
||||||
|
// src/common/sdk/nvidia/inc/class/cl2081.h.
|
||||||
|
//
|
||||||
|
// +marshal
|
||||||
|
type NV2081_ALLOC_PARAMETERS struct {
|
||||||
|
Reserved uint32
|
||||||
|
}
|
||||||
|
|
||||||
|
// NV0005_ALLOC_PARAMETERS is the alloc params type for NV01_EVENT* classes
|
||||||
|
// from src/common/sdk/nvidia/inc/class/cl0005.h.
|
||||||
|
//
|
||||||
|
// +marshal
|
||||||
|
type NV0005_ALLOC_PARAMETERS struct {
|
||||||
|
HParentClient Handle
|
||||||
|
HSrcResource Handle
|
||||||
|
HClass ClassID
|
||||||
|
NotifyIndex uint32
|
||||||
|
Data P64 // actually FD for NV01_EVENT_OS_EVENT, see src/nvidia/src/kernel/rmapi/event.c:eventConstruct_IMPL() => src/nvidia/arch/nvalloc/unix/src/os.c:osUserHandleToKernelPtr()
|
||||||
|
}
|
||||||
|
|
||||||
|
// From src/common/sdk/nvidia/inc/class/cl208f.h
|
||||||
|
const (
|
||||||
|
NV20_SUBDEVICE_DIAG = 0x0000208f
|
||||||
|
)
|
||||||
|
|
||||||
|
// From src/common/sdk/nvidia/inc/class/cl0070.h:
|
||||||
|
const (
|
||||||
|
NV_MEMORY_VIRTUAL_SYSMEM_DYNAMIC_HVASPACE = 0xffffffff
|
||||||
|
)
|
||||||
|
|
||||||
|
// NV_MEMORY_VIRTUAL_ALLOCATION_PARAMS is the alloc params type for
|
||||||
|
// NV01_MEMORY_VIRTUAL, from src/common/sdk/nvidia/inc/class/cl0070.h.
|
||||||
|
//
|
||||||
|
// +marshal
|
||||||
|
type NV_MEMORY_VIRTUAL_ALLOCATION_PARAMS struct {
|
||||||
|
Offset uint64
|
||||||
|
Limit uint64
|
||||||
|
HVASpace Handle
|
||||||
|
Pad0 [4]byte
|
||||||
|
}
|
||||||
|
|
||||||
|
// From src/common/sdk/nvidia/inc/class/cl0073.h
|
||||||
|
const (
|
||||||
|
NV04_DISPLAY_COMMON = 0x00000073
|
||||||
|
)
|
||||||
|
|
||||||
|
// NV0080_ALLOC_PARAMETERS is the alloc params type for NV01_DEVICE_0, from
|
||||||
|
// src/common/sdk/nvidia/inc/class/cl0080.h.
|
||||||
|
//
|
||||||
|
// +marshal
|
||||||
|
type NV0080_ALLOC_PARAMETERS struct {
|
||||||
|
DeviceID uint32
|
||||||
|
HClientShare Handle
|
||||||
|
HTargetClient Handle
|
||||||
|
HTargetDevice Handle
|
||||||
|
Flags uint32
|
||||||
|
Pad0 [4]byte
|
||||||
|
VASpaceSize uint64
|
||||||
|
VAStartInternal uint64
|
||||||
|
VALimitInternal uint64
|
||||||
|
VAMode uint32
|
||||||
|
Pad1 [4]byte
|
||||||
|
}
|
||||||
|
|
||||||
|
// NV_SEMAPHORE_SURFACE_ALLOC_PARAMETERS is the alloc params type for
|
||||||
|
// NV_SEMAPHORE_SURFACE, from src/common/sdk/nvidia/inc/class/cl00da.h.
|
||||||
|
//
|
||||||
|
// +marshal
|
||||||
|
type NV_SEMAPHORE_SURFACE_ALLOC_PARAMETERS struct {
|
||||||
|
HSemaphoreMem Handle
|
||||||
|
HMaxSubmittedMem Handle
|
||||||
|
flags uint64
|
||||||
|
}
|
||||||
|
|
||||||
|
// NV2080_ALLOC_PARAMETERS is the alloc params type for NV20_SUBDEVICE_0, from
|
||||||
|
// src/common/sdk/nvidia/inc/class/cl2080.h.
|
||||||
|
//
|
||||||
|
// +marshal
|
||||||
|
type NV2080_ALLOC_PARAMETERS struct {
|
||||||
|
SubDeviceID uint32
|
||||||
|
}
|
||||||
|
|
||||||
|
// NV_CONTEXT_DMA_ALLOCATION_PARAMS is the alloc params type for various NV01_CONTEXT_DMA
|
||||||
|
// allocation classes, from src/common/sdk/nvidia/inc/nvos.h.
|
||||||
|
//
|
||||||
|
// +marshal
|
||||||
|
type NV_CONTEXT_DMA_ALLOCATION_PARAMS struct {
|
||||||
|
HSubDevice Handle
|
||||||
|
Flags uint32
|
||||||
|
HMemory Handle
|
||||||
|
_ uint32
|
||||||
|
Offset uint64
|
||||||
|
Limit uint64
|
||||||
|
}
|
||||||
|
|
||||||
|
// NV_MEMORY_ALLOCATION_PARAMS is the alloc params type for various NV*_MEMORY*
|
||||||
|
// allocation classes, from src/common/sdk/nvidia/inc/nvos.h.
|
||||||
|
//
|
||||||
|
// +marshal
|
||||||
|
type NV_MEMORY_ALLOCATION_PARAMS struct {
|
||||||
|
Owner uint32
|
||||||
|
Type uint32
|
||||||
|
Flags uint32
|
||||||
|
Width uint32
|
||||||
|
Height uint32
|
||||||
|
Pitch int32
|
||||||
|
Attr uint32
|
||||||
|
Attr2 uint32
|
||||||
|
Format uint32
|
||||||
|
ComprCovg uint32
|
||||||
|
ZcullCovg uint32
|
||||||
|
_ uint32
|
||||||
|
RangeLo uint64
|
||||||
|
RangeHi uint64
|
||||||
|
Size uint64
|
||||||
|
Alignment uint64
|
||||||
|
Offset uint64
|
||||||
|
Limit uint64
|
||||||
|
Address P64
|
||||||
|
CtagOffset uint32
|
||||||
|
HVASpace Handle
|
||||||
|
InternalFlags uint32
|
||||||
|
Tag uint32
|
||||||
|
}
|
||||||
|
|
||||||
|
// NV_MEMORY_ALLOCATION_PARAMS_V545 is the updated version of
|
||||||
|
// NV_MEMORY_ALLOCATION_PARAMS since 545.23.06.
|
||||||
|
//
|
||||||
|
// +marshal
|
||||||
|
type NV_MEMORY_ALLOCATION_PARAMS_V545 struct {
|
||||||
|
NV_MEMORY_ALLOCATION_PARAMS
|
||||||
|
NumaNode int32
|
||||||
|
_ uint32
|
||||||
|
}
|
||||||
|
|
||||||
|
// NV503B_BAR1_P2P_DMA_INFO from src/common/sdk/nvidia/inc/class/cl503b.h.
|
||||||
|
//
|
||||||
|
// +marshal
|
||||||
|
type NV503B_BAR1_P2P_DMA_INFO struct {
|
||||||
|
DmaAddress uint64
|
||||||
|
DmaSize uint64
|
||||||
|
}
|
||||||
|
|
||||||
|
// NV503B_ALLOC_PARAMETERS is the alloc params type for NV50_P2P, from
|
||||||
|
// src/common/sdk/nvidia/inc/class/cl503b.h.
|
||||||
|
//
|
||||||
|
// +marshal
|
||||||
|
type NV503B_ALLOC_PARAMETERS struct {
|
||||||
|
HSubDevice Handle
|
||||||
|
HPeerSubDevice Handle
|
||||||
|
SubDevicePeerIDMask uint32
|
||||||
|
PeerSubDevicePeerIDMask uint32
|
||||||
|
MailboxBar1Addr uint64
|
||||||
|
MailboxTotalSize uint32
|
||||||
|
Flags uint32
|
||||||
|
SubDeviceEgmPeerIDMask uint32
|
||||||
|
PeerSubDeviceEgmPeerIDMask uint32
|
||||||
|
L2pBar1P2PDmaInfo NV503B_BAR1_P2P_DMA_INFO
|
||||||
|
P2lBar1P2PDmaInfo NV503B_BAR1_P2P_DMA_INFO
|
||||||
|
}
|
||||||
|
|
||||||
|
// NV503C_ALLOC_PARAMETERS is the alloc params type for NV50_THIRD_PARTY_P2P,
|
||||||
|
// from src/common/sdk/nvidia/inc/class/cl503c.h.
|
||||||
|
//
|
||||||
|
// +marshal
|
||||||
|
type NV503C_ALLOC_PARAMETERS struct {
|
||||||
|
Flags uint32
|
||||||
|
}
|
||||||
|
|
||||||
|
// NV83DE_ALLOC_PARAMETERS is the alloc params type for GT200_DEBUGGER,
|
||||||
|
// from src/common/sdk/nvidia/inc/class/cl83de.h.
|
||||||
|
//
|
||||||
|
// +marshal
|
||||||
|
type NV83DE_ALLOC_PARAMETERS struct {
|
||||||
|
HDebuggerClient_Obsolete Handle
|
||||||
|
HAppClient Handle
|
||||||
|
HClass3DObject Handle
|
||||||
|
}
|
||||||
|
|
||||||
|
// NV_CTXSHARE_ALLOCATION_PARAMETERS is the alloc params type for
|
||||||
|
// FERMI_CONTEXT_SHARE_A, from src/common/sdk/nvidia/inc/nvos.h.
|
||||||
|
//
|
||||||
|
// +marshal
|
||||||
|
type NV_CTXSHARE_ALLOCATION_PARAMETERS struct {
|
||||||
|
HVASpace Handle
|
||||||
|
Flags uint32
|
||||||
|
SubctxID uint32
|
||||||
|
}
|
||||||
|
|
||||||
|
// NV_VASPACE_ALLOCATION_PARAMETERS is the alloc params type for
|
||||||
|
// FERMI_VASPACE_A, from src/common/sdk/nvidia/inc/nvos.h.
|
||||||
|
//
|
||||||
|
// +marshal
|
||||||
|
type NV_VASPACE_ALLOCATION_PARAMETERS struct {
|
||||||
|
Index uint32
|
||||||
|
Flags uint32
|
||||||
|
VASize uint64
|
||||||
|
VAStartInternal uint64
|
||||||
|
VALimitInternal uint64
|
||||||
|
BigPageSize uint32
|
||||||
|
Pad0 [4]byte
|
||||||
|
VABase uint64
|
||||||
|
}
|
||||||
|
|
||||||
|
// NV_VASPACE_ALLOCATION_PARAMETERS_V580 is the updated version of
|
||||||
|
// NV_VASPACE_ALLOCATION_PARAMETERS since 580.65.06.
|
||||||
|
//
|
||||||
|
// +marshal
|
||||||
|
type NV_VASPACE_ALLOCATION_PARAMETERS_V580 struct {
|
||||||
|
NV_VASPACE_ALLOCATION_PARAMETERS
|
||||||
|
Pasid uint32
|
||||||
|
Pad1 [4]byte
|
||||||
|
}
|
||||||
|
|
||||||
|
// NV_CHANNEL_GROUP_ALLOCATION_PARAMETERS is the alloc params type for
|
||||||
|
// KEPLER_CHANNEL_GROUP_A, from src/common/sdk/nvidia/inc/nvos.h.
|
||||||
|
//
|
||||||
|
// +marshal
|
||||||
|
type NV_CHANNEL_GROUP_ALLOCATION_PARAMETERS struct {
|
||||||
|
HObjectError Handle
|
||||||
|
HObjectECCError Handle
|
||||||
|
HVASpace Handle
|
||||||
|
EngineType uint32
|
||||||
|
BIsCallingContextVgpuPlugin uint8
|
||||||
|
Pad0 [3]byte
|
||||||
|
}
|
||||||
|
|
||||||
|
// NV_MEMORY_DESC_PARAMS is from
|
||||||
|
// src/common/sdk/nvidia/inc/alloc/alloc_channel.h.
|
||||||
|
//
|
||||||
|
// +marshal
|
||||||
|
type NV_MEMORY_DESC_PARAMS struct {
|
||||||
|
Base uint64
|
||||||
|
Size uint64
|
||||||
|
AddressSpace uint32
|
||||||
|
CacheAttrib uint32
|
||||||
|
}
|
||||||
|
|
||||||
|
// NV_BSP_ALLOCATION_PARAMETERS is the alloc params type for
|
||||||
|
// NV*VIDEO_DECODER, from src/common/sdk/nvidia/inc/nvos.h.
|
||||||
|
//
|
||||||
|
// +marshal
|
||||||
|
type NV_BSP_ALLOCATION_PARAMETERS struct {
|
||||||
|
Size uint32
|
||||||
|
ProhibitMultipleInstances uint32
|
||||||
|
EngineInstance uint32
|
||||||
|
}
|
||||||
|
|
||||||
|
// NV_MSENC_ALLOCATION_PARAMETERS is the alloc params type for
|
||||||
|
// NV*_VIDEO_ENCODER, from src/common/sdk/nvidia/inc/nvos.h.
|
||||||
|
//
|
||||||
|
// +marshal
|
||||||
|
type NV_MSENC_ALLOCATION_PARAMETERS struct {
|
||||||
|
Size uint32
|
||||||
|
ProhibitMultipleInstances uint32
|
||||||
|
EngineInstance uint32
|
||||||
|
}
|
||||||
|
|
||||||
|
// NV_CHANNEL_ALLOC_PARAMS is the alloc params type for TURING_CHANNEL_GPFIFO_A
|
||||||
|
// and AMPERE_CHANNEL_GPFIFO_A, from
|
||||||
|
// src/common/sdk/nvidia/inc/alloc/alloc_channel.h.
|
||||||
|
//
|
||||||
|
// +marshal
|
||||||
|
type NV_CHANNEL_ALLOC_PARAMS struct {
|
||||||
|
HObjectError Handle
|
||||||
|
HObjectBuffer Handle
|
||||||
|
GPFIFOOffset uint64
|
||||||
|
GPFIFOEntries uint32
|
||||||
|
Flags uint32
|
||||||
|
HContextShare Handle
|
||||||
|
HVASpace Handle
|
||||||
|
HUserdMemory [NV_MAX_SUBDEVICES]Handle
|
||||||
|
UserdOffset [NV_MAX_SUBDEVICES]uint64
|
||||||
|
EngineType uint32
|
||||||
|
CID uint32
|
||||||
|
SubDeviceID uint32
|
||||||
|
HObjectECCError Handle
|
||||||
|
InstanceMem NV_MEMORY_DESC_PARAMS
|
||||||
|
UserdMem NV_MEMORY_DESC_PARAMS
|
||||||
|
RamfcMem NV_MEMORY_DESC_PARAMS
|
||||||
|
MthdbufMem NV_MEMORY_DESC_PARAMS
|
||||||
|
HPhysChannelGroup Handle
|
||||||
|
InternalFlags uint32
|
||||||
|
ErrorNotifierMem NV_MEMORY_DESC_PARAMS
|
||||||
|
ECCErrorNotifierMem NV_MEMORY_DESC_PARAMS
|
||||||
|
ProcessID uint32
|
||||||
|
SubProcessID uint32
|
||||||
|
EncryptIv [CC_CHAN_ALLOC_IV_SIZE_DWORD]uint32
|
||||||
|
DecryptIv [CC_CHAN_ALLOC_IV_SIZE_DWORD]uint32
|
||||||
|
HmacNonce [CC_CHAN_ALLOC_NONCE_SIZE_DWORD]uint32
|
||||||
|
}
|
||||||
|
|
||||||
|
// NV_CHANNEL_ALLOC_PARAMS_V570 is the updated version of
|
||||||
|
// NV_CHANNEL_ALLOC_PARAMS since 570.86.15.
|
||||||
|
//
|
||||||
|
// +marshal
|
||||||
|
type NV_CHANNEL_ALLOC_PARAMS_V570 struct {
|
||||||
|
NV_CHANNEL_ALLOC_PARAMS
|
||||||
|
TPCConfigID uint32
|
||||||
|
_ uint32
|
||||||
|
}
|
||||||
|
|
||||||
|
// NVB0B5_ALLOCATION_PARAMETERS is the alloc param type for TURING_DMA_COPY_A,
|
||||||
|
// AMPERE_DMA_COPY_A, and AMPERE_DMA_COPY_B from
|
||||||
|
// src/common/sdk/nvidia/inc/class/clb0b5sw.h.
|
||||||
|
//
|
||||||
|
// +marshal
|
||||||
|
type NVB0B5_ALLOCATION_PARAMETERS struct {
|
||||||
|
Version uint32
|
||||||
|
EngineType uint32
|
||||||
|
}
|
||||||
|
|
||||||
|
// NV_GR_ALLOCATION_PARAMETERS is the alloc param type for TURING_COMPUTE_A,
|
||||||
|
// AMPERE_COMPUTE_A, and ADA_COMPUTE_A, from src/common/sdk/nvidia/inc/nvos.h.
|
||||||
|
//
|
||||||
|
// +marshal
|
||||||
|
type NV_GR_ALLOCATION_PARAMETERS struct {
|
||||||
|
Version uint32
|
||||||
|
Flags uint32
|
||||||
|
Size uint32
|
||||||
|
Caps uint32
|
||||||
|
}
|
||||||
|
|
||||||
|
// NV_HOPPER_USERMODE_A_PARAMS is the alloc param type for HOPPER_USERMODE_A,
|
||||||
|
// from src/common/sdk/nvidia/inc/nvos.h.
|
||||||
|
//
|
||||||
|
// +marshal
|
||||||
|
type NV_HOPPER_USERMODE_A_PARAMS struct {
|
||||||
|
Bar1Mapping uint8
|
||||||
|
Priv uint8
|
||||||
|
}
|
||||||
|
|
||||||
|
// NV9072_ALLOCATION_PARAMETERS is the alloc param type for GF100_DISP_SW,
|
||||||
|
// from src/common/sdk/nvidia/inc/class/cl9072.h.
|
||||||
|
//
|
||||||
|
// +marshal
|
||||||
|
type NV9072_ALLOCATION_PARAMETERS struct {
|
||||||
|
LogicalHeadID uint32
|
||||||
|
DisplayMask uint32
|
||||||
|
Caps uint32
|
||||||
|
}
|
||||||
|
|
||||||
|
// NV00DE_ALLOC_PARAMETERS is the alloc param type for RM_USER_SHARED_DATA,
|
||||||
|
// from src/common/sdk/nvidia/inc/class/cl00de.h.
|
||||||
|
//
|
||||||
|
// +marshal
|
||||||
|
type NV00DE_ALLOC_PARAMETERS struct {
|
||||||
|
Reserved uint32
|
||||||
|
}
|
||||||
|
|
||||||
|
// NV00DE_ALLOC_PARAMETERS_V545 is the updated version of
|
||||||
|
// NV00DE_ALLOC_PARAMETERS since 545.23.06.
|
||||||
|
//
|
||||||
|
// +marshal
|
||||||
|
type NV00DE_ALLOC_PARAMETERS_V545 struct {
|
||||||
|
PolledDataMask uint64
|
||||||
|
}
|
||||||
|
|
||||||
|
// +marshal
|
||||||
|
type nv00f8Map struct {
|
||||||
|
offset uint64
|
||||||
|
hVidMem Handle
|
||||||
|
flags uint32
|
||||||
|
}
|
||||||
|
|
||||||
|
// NV00F8_ALLOCATION_PARAMETERS is the alloc param type for NV_MEMORY_FABRIC,
|
||||||
|
// from src/common/sdk/nvidia/inc/class/cl00f8.h.
|
||||||
|
//
|
||||||
|
// +marshal
|
||||||
|
type NV00F8_ALLOCATION_PARAMETERS struct {
|
||||||
|
Alignment uint64
|
||||||
|
AllocSize uint64
|
||||||
|
PageSize uint64
|
||||||
|
AllocFlags uint32
|
||||||
|
_ uint32
|
||||||
|
Map nv00f8Map
|
||||||
|
}
|
||||||
|
|
||||||
|
// From src/common/sdk/nvidia/inc/class/cl00e0.h
|
||||||
|
const (
|
||||||
|
NV_MEM_EXPORT_UUID_LEN = 16
|
||||||
|
)
|
||||||
|
|
||||||
|
// NV_EXPORT_MEM_PACKET is from
|
||||||
|
// src/common/sdk/nvidia/inc/class/cl00e0.h
|
||||||
|
//
|
||||||
|
// +marshal
|
||||||
|
type NV_EXPORT_MEM_PACKET struct {
|
||||||
|
UUID [NV_MEM_EXPORT_UUID_LEN]uint8
|
||||||
|
Opaque [16]uint8
|
||||||
|
}
|
||||||
|
|
||||||
|
// NV00FD_ALLOCATION_PARAMETERS is the alloc param type for NV_MEMORY_MULTICAST_FABRIC
|
||||||
|
// from src/common/sdk/nvidia/inc/class/cl00fd.h
|
||||||
|
//
|
||||||
|
// +marshal
|
||||||
|
type NV00FD_ALLOCATION_PARAMETERS struct {
|
||||||
|
Alignment uint64
|
||||||
|
AllocSize uint64
|
||||||
|
PageSize uint32
|
||||||
|
AllocFlags uint32
|
||||||
|
NumGPUs uint32
|
||||||
|
_ uint32
|
||||||
|
POsEvent P64
|
||||||
|
}
|
||||||
|
|
||||||
|
// NV00FD_ALLOCATION_PARAMETERS_V545 is the updated version of
|
||||||
|
// NV00FD_ALLOCATION_PARAMETERS since 545.23.06.
|
||||||
|
//
|
||||||
|
// +marshal
|
||||||
|
type NV00FD_ALLOCATION_PARAMETERS_V545 struct {
|
||||||
|
ExpPacket NV_EXPORT_MEM_PACKET
|
||||||
|
Index uint16
|
||||||
|
_ [6]byte
|
||||||
|
NV00FD_ALLOCATION_PARAMETERS
|
||||||
|
}
|
||||||
|
|
||||||
|
// NV_MEMORY_MAPPER_ALLOCATION_PARAMS is the alloc param type for
|
||||||
|
// NV_MEMORY_MAPPER, from src/common/sdk/nvidia/inc/class/cl00fe.h.
|
||||||
|
//
|
||||||
|
// +marshal
|
||||||
|
type NV_MEMORY_MAPPER_ALLOCATION_PARAMS struct {
|
||||||
|
unused uint8
|
||||||
|
}
|
||||||
|
|
||||||
|
// NV_MEMORY_MAPPER_ALLOCATION_PARAMS_V550 is the updated version of
|
||||||
|
// NV_MEMORY_MAPPER_ALLOCATION_PARAMS since 550.40.07.
|
||||||
|
//
|
||||||
|
// +marshal
|
||||||
|
type NV_MEMORY_MAPPER_ALLOCATION_PARAMS_V550 struct {
|
||||||
|
HSemaphoreSurface Handle
|
||||||
|
MaxQueueSize uint32
|
||||||
|
}
|
||||||
|
|
||||||
|
// NV_MEMORY_MAPPER_ALLOCATION_PARAMS_V555 is the updated version of
|
||||||
|
// NV_MEMORY_MAPPER_ALLOCATION_PARAMS_V550 since 555.42.02.
|
||||||
|
//
|
||||||
|
// +marshal
|
||||||
|
type NV_MEMORY_MAPPER_ALLOCATION_PARAMS_V555 struct {
|
||||||
|
NV_MEMORY_MAPPER_ALLOCATION_PARAMS_V550
|
||||||
|
HNotificationMemory Handle
|
||||||
|
_ uint32
|
||||||
|
NotificationOffset uint64
|
||||||
|
}
|
||||||
|
|
||||||
|
// NV_CONFIDENTIAL_COMPUTE_ALLOC_PARAMS is the alloc param type for
|
||||||
|
// NV_CONFIDENTIAL_COMPUTE, from src/common/sdk/nvidia/inc/class/clcb33.h.
|
||||||
|
//
|
||||||
|
// +marshal
|
||||||
|
type NV_CONFIDENTIAL_COMPUTE_ALLOC_PARAMS struct {
|
||||||
|
Handle Handle
|
||||||
|
}
|
||||||
|
|
||||||
|
// NVA0BC_ALLOC_PARAMETERS is the alloc param type for
|
||||||
|
// NVENC_SW_SESSION, from src/common/sdk/nvidia/inc/class/cla0bc.h
|
||||||
|
//
|
||||||
|
// +marshal
|
||||||
|
type NVA0BC_ALLOC_PARAMETERS struct {
|
||||||
|
CodecType uint32
|
||||||
|
HResolution uint32
|
||||||
|
VResolution uint32
|
||||||
|
Version uint32
|
||||||
|
HMem Handle
|
||||||
|
}
|
||||||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue