Fix up and add some iptables ABI.

PiperOrigin-RevId: 259437060
This commit is contained in:
Kevin Krakauer
2019-07-22 17:06:18 -07:00
committed by gVisor bot
parent d706922d78
commit 5ddf9adb2b
3 changed files with 142 additions and 8 deletions
+11 -1
View File
@@ -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",
],
)
+86 -7
View File
@@ -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)
}
+45
View File
@@ -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)
}
}
}