summaryrefslogtreecommitdiffhomepage
path: root/pkg
diff options
context:
space:
mode:
authorKevin Krakauer <krakauer@google.com>2019-07-22 17:05:02 -0700
committergVisor bot <gvisor-bot@google.com>2019-07-22 17:06:18 -0700
commit5ddf9adb2b12a2cbccdcf609c5cc140fa0dbd81d (patch)
treee29d183459766c34e399b9094e21e67af4646d21 /pkg
parentd706922d788a1bbc9f1c917af1a08ca86488aab0 (diff)
Fix up and add some iptables ABI.
PiperOrigin-RevId: 259437060
Diffstat (limited to 'pkg')
-rw-r--r--pkg/abi/linux/BUILD12
-rw-r--r--pkg/abi/linux/netfilter.go93
-rw-r--r--pkg/abi/linux/netfilter_test.go45
3 files changed, 142 insertions, 8 deletions
diff --git a/pkg/abi/linux/BUILD b/pkg/abi/linux/BUILD
index 2061b38c0..ba233b93f 100644
--- a/pkg/abi/linux/BUILD
+++ b/pkg/abi/linux/BUILD
@@ -4,7 +4,7 @@
package(licenses = ["notice"])
-load("//tools/go_stateify:defs.bzl", "go_library")
+load("//tools/go_stateify:defs.bzl", "go_library", "go_test")
go_library(
name = "linux",
@@ -62,3 +62,13 @@ go_library(
"//pkg/bits",
],
)
+
+go_test(
+ name = "linux_test",
+ size = "small",
+ srcs = ["netfilter_test.go"],
+ embed = [":linux"],
+ deps = [
+ "//pkg/binary",
+ ],
+)
diff --git a/pkg/abi/linux/netfilter.go b/pkg/abi/linux/netfilter.go
index 7f399142b..269ba5567 100644
--- a/pkg/abi/linux/netfilter.go
+++ b/pkg/abi/linux/netfilter.go
@@ -100,6 +100,21 @@ type IPTEntry struct {
// Elems [0]byte
}
+// SizeOfIPTEntry is the size of an IPTEntry.
+const SizeOfIPTEntry = 112
+
+// KernelIPTEntry is identical to IPTEntry, but includes the Elems field. This
+// struct marshaled via the binary package to write an IPTEntry to userspace.
+type KernelIPTEntry struct {
+ 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 []byte
+}
+
// 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.
@@ -123,10 +138,10 @@ type IPTIP struct {
OutputInterface [IFNAMSIZ]byte
// InputInterfaceMask is the intput interface mask.
- InputInterfaceMast [IFNAMSIZ]byte
+ InputInterfaceMask [IFNAMSIZ]byte
// OuputInterfaceMask is the output interface mask.
- OuputInterfaceMask [IFNAMSIZ]byte
+ OutputInterfaceMask [IFNAMSIZ]byte
// Protocol is the transport protocol.
Protocol uint16
@@ -138,6 +153,9 @@ type IPTIP struct {
InverseFlags uint8
}
+// 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.
type XTCounters struct {
@@ -148,6 +166,9 @@ type XTCounters struct {
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.
@@ -160,11 +181,14 @@ type XTEntryMatch struct {
MatchSize uint16
Name [XT_EXTENSION_MAXNAMELEN]byte
Revision uint8
- // Data is omitted here because it would cause XTEntryTarget to be an
+ // 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
+
// 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.
@@ -174,22 +198,29 @@ type XTEntryMatch struct {
// exposing different data to the user and kernel, but this struct holds only
// the user data.
type XTEntryTarget struct {
- MatchSize uint16
- Name [XT_EXTENSION_MAXNAMELEN]byte
- Revision uint8
+ TargetSize uint16
+ Name [XT_EXTENSION_MAXNAMELEN]byte
+ 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
+
// XTStandardTarget is a builtin target, one of ACCEPT, DROP, JUMP, QUEUE, or
// RETURN. It corresponds to struct xt_standard_target in
// include/uapi/linux/netfilter/x_tables.h.
type XTStandardTarget struct {
Target XTEntryTarget
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
@@ -197,8 +228,12 @@ type XTStandardTarget struct {
type XTErrorTarget struct {
Target XTEntryTarget
ErrorName [XT_FUNCTION_MAXNAMELEN]byte
+ _ [2]byte
}
+// SizeOfXTErrorTarget is the size of an XTErrorTarget.
+const SizeOfXTErrorTarget = 64
+
// 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.
type IPTGetinfo struct {
@@ -210,18 +245,50 @@ type IPTGetinfo struct {
Size uint32
}
+// SizeOfIPTGetinfo is the size of an IPTGetinfo.
+const SizeOfIPTGetinfo = 84
+
+// TableName returns the table name.
+func (info *IPTGetinfo) TableName() string {
+ return tableName(info.Name[:])
+}
+
// 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.
type IPTGetEntries struct {
Name [XT_TABLE_MAXNAMELEN]byte
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
}
+// TableName returns the entries' table name.
+func (entries *IPTGetEntries) TableName() string {
+ return tableName(entries.Name[:])
+}
+
+// SizeOfIPTGetEntries is the size of an IPTGetEntries.
+const SizeOfIPTGetEntries = 40
+
+// KernelIPTGetEntries is identical to IPTEntry, but includes the Elems field.
+// This struct marshaled via the binary package to write an KernelIPTGetEntries
+// to userspace.
+type KernelIPTGetEntries struct {
+ Name [XT_TABLE_MAXNAMELEN]byte
+ Size uint32
+ _ [4]byte
+ Entrytable []KernelIPTEntry
+}
+
+// TableName returns the entries' table name.
+func (entries *KernelIPTGetEntries) TableName() string {
+ return tableName(entries.Name[:])
+}
+
// 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.
@@ -233,8 +300,20 @@ type IPTReplace struct {
HookEntry [NF_INET_NUMHOOKS]uint32
Underflow [NF_INET_NUMHOOKS]uint32
NumCounters uint32
- Counters *XTCounters
+ 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
+
+func tableName(name []byte) string {
+ for i, c := range name {
+ if c == 0 {
+ return string(name[:i])
+ }
+ }
+ return string(name)
+}
diff --git a/pkg/abi/linux/netfilter_test.go b/pkg/abi/linux/netfilter_test.go
new file mode 100644
index 000000000..21e237f92
--- /dev/null
+++ b/pkg/abi/linux/netfilter_test.go
@@ -0,0 +1,45 @@
+// 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 (
+ "testing"
+
+ "gvisor.dev/gvisor/pkg/binary"
+)
+
+func TestSizes(t *testing.T) {
+ testCases := []struct {
+ typ interface{}
+ defined uintptr
+ }{
+ {IPTEntry{}, SizeOfIPTEntry},
+ {IPTGetEntries{}, SizeOfIPTGetEntries},
+ {IPTGetinfo{}, SizeOfIPTGetinfo},
+ {IPTIP{}, SizeOfIPTIP},
+ {IPTReplace{}, SizeOfIPTReplace},
+ {XTCounters{}, SizeOfXTCounters},
+ {XTEntryMatch{}, SizeOfXTEntryMatch},
+ {XTEntryTarget{}, SizeOfXTEntryTarget},
+ {XTErrorTarget{}, SizeOfXTErrorTarget},
+ {XTStandardTarget{}, SizeOfXTStandardTarget},
+ }
+
+ for _, tc := range testCases {
+ if calculated := binary.Size(tc.typ); calculated != tc.defined {
+ t.Errorf("%T has a defined size of %d and calculated size of %d", tc.typ, tc.defined, calculated)
+ }
+ }
+}