mirror of
https://github.com/netbirdio/gvisor.git
synced 2026-05-22 17:12:49 -07:00
Addressed GH comments
This commit is contained in:
@@ -298,6 +298,7 @@ type IPTReplace struct {
|
||||
// Entries [0]IPTEntry
|
||||
}
|
||||
|
||||
// KernelIPTEntry is identical to IPTReplace, but includes the Entries field.
|
||||
type KernelIPTReplace struct {
|
||||
IPTReplace
|
||||
Entries [0]IPTEntry
|
||||
@@ -306,28 +307,32 @@ type KernelIPTReplace struct {
|
||||
// SizeOfIPTReplace is the size of an IPTReplace.
|
||||
const SizeOfIPTReplace = 96
|
||||
|
||||
// ExtensionName holds the name of a netfilter extension.
|
||||
type ExtensionName [XT_EXTENSION_MAXNAMELEN]byte
|
||||
|
||||
// String implements fmt.Stringer.
|
||||
func (en ExtensionName) String() string {
|
||||
return name(en[:])
|
||||
return goString(en[:])
|
||||
}
|
||||
|
||||
// ExtensionName holds the name of a netfilter table.
|
||||
type TableName [XT_TABLE_MAXNAMELEN]byte
|
||||
|
||||
// String implements fmt.Stringer.
|
||||
func (tn TableName) String() string {
|
||||
return name(tn[:])
|
||||
return goString(tn[:])
|
||||
}
|
||||
|
||||
// ExtensionName holds the name of a netfilter error. These can also hold
|
||||
// user-defined chains.
|
||||
type ErrorName [XT_FUNCTION_MAXNAMELEN]byte
|
||||
|
||||
// String implements fmt.Stringer.
|
||||
func (fn ErrorName) String() string {
|
||||
return name(fn[:])
|
||||
func (en ErrorName) String() string {
|
||||
return goString(en[:])
|
||||
}
|
||||
|
||||
func name(cstring []byte) string {
|
||||
func goString(cstring []byte) string {
|
||||
for i, c := range cstring {
|
||||
if c == 0 {
|
||||
return string(cstring[:i])
|
||||
|
||||
@@ -53,7 +53,7 @@ func GetInfo(t *kernel.Task, ep tcpip.Endpoint, outPtr usermem.Addr) (linux.IPTG
|
||||
}
|
||||
|
||||
// Find the appropriate table.
|
||||
table, err := findTable(ep, info.Name.String())
|
||||
table, err := findTable(ep, info.Name)
|
||||
if err != nil {
|
||||
return linux.IPTGetinfo{}, err
|
||||
}
|
||||
@@ -84,7 +84,7 @@ func GetEntries(t *kernel.Task, ep tcpip.Endpoint, outPtr usermem.Addr, outLen i
|
||||
}
|
||||
|
||||
// Find the appropriate table.
|
||||
table, err := findTable(ep, userEntries.Name.String())
|
||||
table, err := findTable(ep, userEntries.Name)
|
||||
if err != nil {
|
||||
return linux.KernelIPTGetEntries{}, err
|
||||
}
|
||||
@@ -96,19 +96,19 @@ func GetEntries(t *kernel.Task, ep tcpip.Endpoint, outPtr usermem.Addr, outLen i
|
||||
return linux.KernelIPTGetEntries{}, err
|
||||
}
|
||||
if binary.Size(entries) > uintptr(outLen) {
|
||||
log.Infof("Insufficient GetEntries output size: %d", uintptr(outLen))
|
||||
log.Warningf("Insufficient GetEntries output size: %d", uintptr(outLen))
|
||||
return linux.KernelIPTGetEntries{}, syserr.ErrInvalidArgument
|
||||
}
|
||||
|
||||
return entries, nil
|
||||
}
|
||||
|
||||
func findTable(ep tcpip.Endpoint, tableName string) (iptables.Table, *syserr.Error) {
|
||||
func findTable(ep tcpip.Endpoint, tablename linux.TableName) (iptables.Table, *syserr.Error) {
|
||||
ipt, err := ep.IPTables()
|
||||
if err != nil {
|
||||
return iptables.Table{}, syserr.FromError(err)
|
||||
}
|
||||
table, ok := ipt.Tables[tableName]
|
||||
table, ok := ipt.Tables[tablename.String()]
|
||||
if !ok {
|
||||
return iptables.Table{}, syserr.ErrInvalidArgument
|
||||
}
|
||||
@@ -138,17 +138,17 @@ func FillDefaultIPTables(stack *stack.Stack) {
|
||||
// format expected by the iptables tool. Linux stores each table as a binary
|
||||
// blob that can only be traversed by parsing a bit, reading some offsets,
|
||||
// jumping to those offsets, parsing again, etc.
|
||||
func convertNetstackToBinary(name string, table iptables.Table) (linux.KernelIPTGetEntries, metadata, *syserr.Error) {
|
||||
func convertNetstackToBinary(tablename string, table iptables.Table) (linux.KernelIPTGetEntries, metadata, *syserr.Error) {
|
||||
// Return values.
|
||||
var entries linux.KernelIPTGetEntries
|
||||
var meta metadata
|
||||
|
||||
// The table name has to fit in the struct.
|
||||
if linux.XT_TABLE_MAXNAMELEN < len(name) {
|
||||
log.Infof("Table name too long.")
|
||||
if linux.XT_TABLE_MAXNAMELEN < len(tablename) {
|
||||
log.Warningf("Table name %q too long.", tablename)
|
||||
return linux.KernelIPTGetEntries{}, metadata{}, syserr.ErrInvalidArgument
|
||||
}
|
||||
copy(entries.Name[:], name)
|
||||
copy(entries.Name[:], tablename)
|
||||
|
||||
for ruleIdx, rule := range table.Rules {
|
||||
// Is this a chain entry point?
|
||||
@@ -273,11 +273,12 @@ func translateToStandardVerdict(val int32) (iptables.Verdict, *syserr.Error) {
|
||||
case -linux.NF_DROP - 1:
|
||||
return iptables.Drop, nil
|
||||
case -linux.NF_QUEUE - 1:
|
||||
log.Infof("Unsupported iptables verdict QUEUE.")
|
||||
log.Warningf("Unsupported iptables verdict QUEUE.")
|
||||
case linux.NF_RETURN:
|
||||
log.Infof("Unsupported iptables verdict RETURN.")
|
||||
log.Warningf("Unsupported iptables verdict RETURN.")
|
||||
default:
|
||||
log.Warningf("Unknown iptables verdict %d.", val)
|
||||
}
|
||||
log.Infof("Unknown iptables verdict %d.", val)
|
||||
return iptables.Invalid, syserr.ErrInvalidArgument
|
||||
}
|
||||
|
||||
@@ -288,7 +289,7 @@ func SetEntries(stack *stack.Stack, optVal []byte) *syserr.Error {
|
||||
|
||||
// Get the basic rules data (struct ipt_replace).
|
||||
if len(optVal) < linux.SizeOfIPTReplace {
|
||||
log.Infof("netfilter.SetEntries: optVal has insufficient size for replace %d", len(optVal))
|
||||
log.Warningf("netfilter.SetEntries: optVal has insufficient size for replace %d", len(optVal))
|
||||
return syserr.ErrInvalidArgument
|
||||
}
|
||||
var replace linux.IPTReplace
|
||||
@@ -302,7 +303,7 @@ func SetEntries(stack *stack.Stack, optVal []byte) *syserr.Error {
|
||||
case iptables.TablenameFilter:
|
||||
table = iptables.EmptyFilterTable()
|
||||
default:
|
||||
log.Infof(fmt.Sprintf("We don't yet support writing to the %q table (gvisor.dev/issue/170)", replace.Name.String()))
|
||||
log.Warningf("We don't yet support writing to the %q table (gvisor.dev/issue/170)", replace.Name.String())
|
||||
return syserr.ErrInvalidArgument
|
||||
}
|
||||
|
||||
@@ -312,7 +313,7 @@ func SetEntries(stack *stack.Stack, optVal []byte) *syserr.Error {
|
||||
for entryIdx := uint32(0); entryIdx < replace.NumEntries; entryIdx++ {
|
||||
// Get the struct ipt_entry.
|
||||
if len(optVal) < linux.SizeOfIPTEntry {
|
||||
log.Infof("netfilter: optVal has insufficient size for entry %d", len(optVal))
|
||||
log.Warningf("netfilter: optVal has insufficient size for entry %d", len(optVal))
|
||||
return syserr.ErrInvalidArgument
|
||||
}
|
||||
var entry linux.IPTEntry
|
||||
@@ -328,7 +329,7 @@ func SetEntries(stack *stack.Stack, optVal []byte) *syserr.Error {
|
||||
// filtering. We reject any nonzero IPTIP values for now.
|
||||
emptyIPTIP := linux.IPTIP{}
|
||||
if entry.IP != emptyIPTIP {
|
||||
log.Infof("netfilter: non-empty struct iptip found")
|
||||
log.Warningf("netfilter: non-empty struct iptip found")
|
||||
return syserr.ErrInvalidArgument
|
||||
}
|
||||
|
||||
@@ -358,11 +359,11 @@ func SetEntries(stack *stack.Stack, optVal []byte) *syserr.Error {
|
||||
}
|
||||
}
|
||||
if ruleIdx := table.BuiltinChains[hk]; ruleIdx == iptables.HookUnset {
|
||||
log.Infof("Hook %v is unset.", hk)
|
||||
log.Warningf("Hook %v is unset.", hk)
|
||||
return syserr.ErrInvalidArgument
|
||||
}
|
||||
if ruleIdx := table.Underflows[hk]; ruleIdx == iptables.HookUnset {
|
||||
log.Infof("Underflow %v is unset.", hk)
|
||||
log.Warningf("Underflow %v is unset.", hk)
|
||||
return syserr.ErrInvalidArgument
|
||||
}
|
||||
}
|
||||
@@ -385,7 +386,7 @@ func SetEntries(stack *stack.Stack, optVal []byte) *syserr.Error {
|
||||
// along with the number of bytes it occupies in optVal.
|
||||
func parseTarget(optVal []byte) (iptables.Target, uint32, *syserr.Error) {
|
||||
if len(optVal) < linux.SizeOfXTEntryTarget {
|
||||
log.Infof("netfilter: optVal has insufficient size for entry target %d", len(optVal))
|
||||
log.Warningf("netfilter: optVal has insufficient size for entry target %d", len(optVal))
|
||||
return nil, 0, syserr.ErrInvalidArgument
|
||||
}
|
||||
var target linux.XTEntryTarget
|
||||
@@ -395,14 +396,14 @@ func parseTarget(optVal []byte) (iptables.Target, uint32, *syserr.Error) {
|
||||
case "":
|
||||
// Standard target.
|
||||
if len(optVal) < linux.SizeOfXTStandardTarget {
|
||||
log.Infof("netfilter.SetEntries: optVal has insufficient size for standard target %d", len(optVal))
|
||||
log.Warningf("netfilter.SetEntries: optVal has insufficient size for standard target %d", len(optVal))
|
||||
return nil, 0, syserr.ErrInvalidArgument
|
||||
}
|
||||
var target linux.XTStandardTarget
|
||||
var standardTarget linux.XTStandardTarget
|
||||
buf = optVal[:linux.SizeOfXTStandardTarget]
|
||||
binary.Unmarshal(buf, usermem.ByteOrder, &target)
|
||||
binary.Unmarshal(buf, usermem.ByteOrder, &standardTarget)
|
||||
|
||||
verdict, err := translateToStandardVerdict(target.Verdict)
|
||||
verdict, err := translateToStandardVerdict(standardTarget.Verdict)
|
||||
if err != nil {
|
||||
return nil, 0, err
|
||||
}
|
||||
@@ -424,9 +425,9 @@ func parseTarget(optVal []byte) (iptables.Target, uint32, *syserr.Error) {
|
||||
log.Infof("netfilter.SetEntries: optVal has insufficient size for error target %d", len(optVal))
|
||||
return nil, 0, syserr.ErrInvalidArgument
|
||||
}
|
||||
var target linux.XTErrorTarget
|
||||
var errorTarget linux.XTErrorTarget
|
||||
buf = optVal[:linux.SizeOfXTErrorTarget]
|
||||
binary.Unmarshal(buf, usermem.ByteOrder, &target)
|
||||
binary.Unmarshal(buf, usermem.ByteOrder, &errorTarget)
|
||||
|
||||
// Error targets are used in 2 cases:
|
||||
// * An actual error case. These rules have an error
|
||||
@@ -435,11 +436,11 @@ func parseTarget(optVal []byte) (iptables.Target, uint32, *syserr.Error) {
|
||||
// somehow fall through every rule.
|
||||
// * To mark the start of a user defined chain. These
|
||||
// rules have an error with the name of the chain.
|
||||
switch target.Name.String() {
|
||||
switch errorTarget.Name.String() {
|
||||
case errorTargetName:
|
||||
return iptables.PanicTarget{}, linux.SizeOfXTErrorTarget, nil
|
||||
default:
|
||||
log.Infof("Unknown error target %q doesn't exist or isn't supported yet.", target.Name.String())
|
||||
log.Infof("Unknown error target %q doesn't exist or isn't supported yet.", errorTarget.Name.String())
|
||||
return nil, 0, syserr.ErrInvalidArgument
|
||||
}
|
||||
}
|
||||
@@ -449,22 +450,6 @@ func parseTarget(optVal []byte) (iptables.Target, uint32, *syserr.Error) {
|
||||
return nil, 0, syserr.ErrInvalidArgument
|
||||
}
|
||||
|
||||
func chainNameFromHook(hook int) string {
|
||||
switch hook {
|
||||
case linux.NF_INET_PRE_ROUTING:
|
||||
return iptables.ChainNamePrerouting
|
||||
case linux.NF_INET_LOCAL_IN:
|
||||
return iptables.ChainNameInput
|
||||
case linux.NF_INET_FORWARD:
|
||||
return iptables.ChainNameForward
|
||||
case linux.NF_INET_LOCAL_OUT:
|
||||
return iptables.ChainNameOutput
|
||||
case linux.NF_INET_POST_ROUTING:
|
||||
return iptables.ChainNamePostrouting
|
||||
}
|
||||
panic(fmt.Sprintf("Unknown hook %d does not correspond to a builtin chain"))
|
||||
}
|
||||
|
||||
func hookFromLinux(hook int) iptables.Hook {
|
||||
switch hook {
|
||||
case linux.NF_INET_PRE_ROUTING:
|
||||
@@ -489,7 +474,7 @@ func printReplace(optVal []byte) {
|
||||
replaceBuf := optVal[:linux.SizeOfIPTReplace]
|
||||
optVal = optVal[linux.SizeOfIPTReplace:]
|
||||
binary.Unmarshal(replaceBuf, usermem.ByteOrder, &replace)
|
||||
log.Infof("kevin: Replacing table %q: %+v", replace.Name.String(), replace)
|
||||
log.Infof("Replacing table %q: %+v", replace.Name.String(), replace)
|
||||
|
||||
// Read in the list of entries at the end of replace.
|
||||
var totalOffset uint16
|
||||
@@ -497,33 +482,33 @@ func printReplace(optVal []byte) {
|
||||
var entry linux.IPTEntry
|
||||
entryBuf := optVal[:linux.SizeOfIPTEntry]
|
||||
binary.Unmarshal(entryBuf, usermem.ByteOrder, &entry)
|
||||
log.Infof("kevin: Entry %d (total offset %d): %+v", entryIdx, totalOffset, entry)
|
||||
log.Infof("Entry %d (total offset %d): %+v", entryIdx, totalOffset, entry)
|
||||
|
||||
totalOffset += entry.NextOffset
|
||||
if entry.TargetOffset == linux.SizeOfIPTEntry {
|
||||
log.Infof("kevin: Entry has no matches.")
|
||||
log.Infof("Entry has no matches.")
|
||||
} else {
|
||||
log.Infof("kevin: Entry has matches.")
|
||||
log.Infof("Entry has matches.")
|
||||
}
|
||||
|
||||
var target linux.XTEntryTarget
|
||||
targetBuf := optVal[entry.TargetOffset : entry.TargetOffset+linux.SizeOfXTEntryTarget]
|
||||
binary.Unmarshal(targetBuf, usermem.ByteOrder, &target)
|
||||
log.Infof("kevin: Target named %q: %+v", target.Name.String(), target)
|
||||
log.Infof("Target named %q: %+v", target.Name.String(), target)
|
||||
|
||||
switch target.Name.String() {
|
||||
case "":
|
||||
var standardTarget linux.XTStandardTarget
|
||||
stBuf := optVal[entry.TargetOffset : entry.TargetOffset+linux.SizeOfXTStandardTarget]
|
||||
binary.Unmarshal(stBuf, usermem.ByteOrder, &standardTarget)
|
||||
log.Infof("kevin: Standard target with verdict %q (%d).", linux.VerdictStrings[standardTarget.Verdict], standardTarget.Verdict)
|
||||
log.Infof("Standard target with verdict %q (%d).", linux.VerdictStrings[standardTarget.Verdict], standardTarget.Verdict)
|
||||
case errorTargetName:
|
||||
var errorTarget linux.XTErrorTarget
|
||||
etBuf := optVal[entry.TargetOffset : entry.TargetOffset+linux.SizeOfXTErrorTarget]
|
||||
binary.Unmarshal(etBuf, usermem.ByteOrder, &errorTarget)
|
||||
log.Infof("kevin: Error target with name %q.", errorTarget.Name.String())
|
||||
log.Infof("Error target with name %q.", errorTarget.Name.String())
|
||||
default:
|
||||
log.Infof("kevin: Unknown target type.")
|
||||
log.Infof("Unknown target type.")
|
||||
}
|
||||
|
||||
optVal = optVal[entry.NextOffset:]
|
||||
|
||||
@@ -1368,10 +1368,7 @@ func (s *SocketOperations) SetSockOpt(t *kernel.Task, level int, name int, optVa
|
||||
return syserr.ErrNoDevice
|
||||
}
|
||||
// Stack must be a netstack stack.
|
||||
if err := netfilter.SetEntries(stack.(*Stack).Stack, optVal); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
return netfilter.SetEntries(stack.(*Stack).Stack, optVal)
|
||||
|
||||
case linux.IPT_SO_SET_ADD_COUNTERS:
|
||||
// TODO(gvisor.dev/issue/170): Counter support.
|
||||
|
||||
Reference in New Issue
Block a user