Automated rollback of changelist 580051079

PiperOrigin-RevId: 580649803
This commit is contained in:
Kevin Krakauer
2023-11-08 14:04:04 -08:00
committed by gVisor bot
parent 9284335c9d
commit 40ee36ac4c
13 changed files with 90 additions and 172 deletions
+4 -7
View File
@@ -38,14 +38,11 @@ go_library(
)
go_test(
name = "netfilter_x_test",
srcs = ["netfilter_x_test.go"],
embedsrcs = [
"accept_blob",
"istio_blob",
],
name = "netfilter_test",
srcs = ["netfilter_test.go"],
embedsrcs = ["istio_blob"],
library = ":netfilter",
deps = [
":netfilter",
"//pkg/sentry/kernel/auth",
"//pkg/tcpip/stack",
],
Binary file not shown.
@@ -12,17 +12,26 @@
// See the License for the specific language governing permissions and
// limitations under the License.
package netfilter_test
package netfilter
import (
_ "embed"
"testing"
"gvisor.dev/gvisor/pkg/sentry/kernel/auth"
"gvisor.dev/gvisor/pkg/sentry/socket/netfilter"
"gvisor.dev/gvisor/pkg/tcpip/stack"
)
// istioBlob is a golden iptables ruleset generated by Istio. It is already in
// the format ready to by passed to IPT_SO_SET_REPLACE.
//
// Updating this requires running Istio, calling IPT_SO_GET_INFO and
// IPT_SO_GET_ENTRIES, then stitching the structs up. So be careful when
// updating!
//
//go:embed istio_blob
var istioBlob []byte
// FakeIDMapper implements IDMapper.
type FakeIDMapper struct{}
@@ -36,50 +45,12 @@ func (*FakeIDMapper) MapToKGID(auth.GID) auth.KGID {
return 0
}
// istioBlob is an iptables NAT ruleset generated by Istio. It is already in
// the format ready to by passed to IPT_SO_SET_REPLACE.
//
// Updating this requires running Istio, calling IPT_SO_GET_INFO and
// IPT_SO_GET_ENTRIES, then stitching the structs up. So be careful when
// updating!
//
//go:embed istio_blob
var istioBlob []byte
// TestIstioBlob tests that we support the iptables ruleset generated by Istio,
// i.e. that we can parse the rules and set them in netstack.
func TestIstioBlob(t *testing.T) {
mapper := FakeIDMapper{}
stk := stack.New(stack.Options{})
if err := netfilter.SetEntries(&mapper, stk, istioBlob, false); err != nil {
stack := stack.New(stack.Options{})
if err := SetEntries(&mapper, stack, istioBlob, false); err != nil {
t.Fatalf("failed to set Istio rules, try setting enableLogging and running again: %v", err)
}
}
// acceptBlob is an iptables NAT ruleset that instructs iptables to ACCEPT all
// and modify nothing. This is the Linux default: a newly booted machine just
// doesn't NAT anything until someone sets the rules.
//
// Updating this requires running Istio, calling IPT_SO_GET_INFO and
// IPT_SO_GET_ENTRIES, then stitching the structs up. So be careful when
// updating!
//
//go:embed accept_blob
var acceptBlob []byte
// TestAcceptBlob tests that updating the default (all ACCEPT) NAT table with
// an identical table doesn't actually set the modified flag. In doing so, we
// can preserve our performance optimization in which iptables is off until
// non-default rules are set.
func TestAcceptBlob(t *testing.T) {
mapper := FakeIDMapper{}
stk := stack.New(stack.Options{
DefaultIPTables: netfilter.DefaultLinuxTables,
})
if err := netfilter.SetEntries(&mapper, stk, acceptBlob, false); err != nil {
t.Fatalf("failed to set Istio rules, try setting enableLogging and running again: %v", err)
}
if stk.IPTables().Modified() {
t.Fatalf("ACCEPT rules shouldn't cause iptables modifications, but did")
}
}
+4 -12
View File
@@ -49,8 +49,6 @@ func (tcpMarshaler) marshal(mr matcher) []byte {
SourcePortEnd: matcher.sourcePortEnd,
DestinationPortStart: matcher.destinationPortStart,
DestinationPortEnd: matcher.destinationPortEnd,
FlagMask: matcher.flagMask,
FlagCompare: matcher.flagCompare,
}
return marshalEntryMatch(matcherNameTCP, marshal.Marshal(&xttcp))
}
@@ -67,7 +65,10 @@ func (tcpMarshaler) unmarshal(_ IDMapper, buf []byte, filter stack.IPHeaderFilte
matchData.UnmarshalUnsafe(buf)
nflog("parseMatchers: parsed XTTCP: %+v", matchData)
if matchData.Option != 0 || matchData.InverseFlags != 0 {
if matchData.Option != 0 ||
matchData.FlagMask != 0 ||
matchData.FlagCompare != 0 ||
matchData.InverseFlags != 0 {
return nil, fmt.Errorf("unsupported TCP matcher flags set")
}
@@ -80,8 +81,6 @@ func (tcpMarshaler) unmarshal(_ IDMapper, buf []byte, filter stack.IPHeaderFilte
sourcePortEnd: matchData.SourcePortEnd,
destinationPortStart: matchData.DestinationPortStart,
destinationPortEnd: matchData.DestinationPortEnd,
flagMask: matchData.FlagMask,
flagCompare: matchData.FlagCompare,
}, nil
}
@@ -91,8 +90,6 @@ type TCPMatcher struct {
sourcePortEnd uint16
destinationPortStart uint16
destinationPortEnd uint16
flagMask uint8
flagCompare uint8
}
// name implements matcher.name.
@@ -149,10 +146,5 @@ func (tm *TCPMatcher) Match(hook stack.Hook, pkt stack.PacketBufferPtr, _, _ str
return false, false
}
// Check the flags.
if uint8(tcpHeader.Flags())&tm.flagMask != tm.flagCompare {
return false, false
}
return true, false
}
+5 -5
View File
@@ -3388,7 +3388,7 @@ func TestWriteStats(t *testing.T) {
filter := ipt.GetTable(stack.FilterID, false /* ipv6 */)
ruleIdx := filter.BuiltinChains[stack.Output]
filter.Rules[ruleIdx].Target = &stack.DropTarget{}
ipt.ForceReplaceTable(stack.FilterID, filter, false /* ipv6 */)
ipt.ReplaceTable(stack.FilterID, filter, false /* ipv6 */)
},
allowPackets: math.MaxInt32,
expectSent: 0,
@@ -3402,7 +3402,7 @@ func TestWriteStats(t *testing.T) {
filter := ipt.GetTable(stack.NATID, false /* ipv6 */)
ruleIdx := filter.BuiltinChains[stack.Postrouting]
filter.Rules[ruleIdx].Target = &stack.DropTarget{}
ipt.ForceReplaceTable(stack.NATID, filter, false /* ipv6 */)
ipt.ReplaceTable(stack.NATID, filter, false /* ipv6 */)
},
allowPackets: math.MaxInt32,
expectSent: 0,
@@ -3422,7 +3422,7 @@ func TestWriteStats(t *testing.T) {
filter.Rules[ruleIdx].Matchers = []stack.Matcher{&limitedMatcher{nPackets - 1}}
// Make sure the next rule is ACCEPT.
filter.Rules[ruleIdx+1].Target = &stack.AcceptTarget{}
ipt.ForceReplaceTable(stack.FilterID, filter, false /* ipv6 */)
ipt.ReplaceTable(stack.FilterID, filter, false /* ipv6 */)
},
allowPackets: math.MaxInt32,
expectSent: nPackets - 1,
@@ -3442,7 +3442,7 @@ func TestWriteStats(t *testing.T) {
filter.Rules[ruleIdx].Matchers = []stack.Matcher{&limitedMatcher{nPackets - 1}}
// Make sure the next rule is ACCEPT.
filter.Rules[ruleIdx+1].Target = &stack.AcceptTarget{}
ipt.ForceReplaceTable(stack.NATID, filter, false /* ipv6 */)
ipt.ReplaceTable(stack.NATID, filter, false /* ipv6 */)
},
allowPackets: math.MaxInt32,
expectSent: nPackets - 1,
@@ -3805,7 +3805,7 @@ func TestCloseLocking(t *testing.T) {
stack.Postrouting: 3,
},
}
s.IPTables().ForceReplaceTable(stack.NATID, table, false /* ipv6 */)
s.IPTables().ReplaceTable(stack.NATID, table, false /* ipv6 */)
e := channel.New(0, defaultMTU, "")
defer e.Close()
+4 -4
View File
@@ -2519,7 +2519,7 @@ func TestWriteStats(t *testing.T) {
filter := ipt.GetTable(stack.FilterID, true /* ipv6 */)
ruleIdx := filter.BuiltinChains[stack.Output]
filter.Rules[ruleIdx].Target = &stack.DropTarget{}
ipt.ForceReplaceTable(stack.FilterID, filter, true /* ipv6 */)
ipt.ReplaceTable(stack.FilterID, filter, true /* ipv6 */)
},
allowPackets: math.MaxInt32,
expectSent: 0,
@@ -2534,7 +2534,7 @@ func TestWriteStats(t *testing.T) {
filter := ipt.GetTable(stack.NATID, true /* ipv6 */)
ruleIdx := filter.BuiltinChains[stack.Postrouting]
filter.Rules[ruleIdx].Target = &stack.DropTarget{}
ipt.ForceReplaceTable(stack.NATID, filter, true /* ipv6 */)
ipt.ReplaceTable(stack.NATID, filter, true /* ipv6 */)
},
allowPackets: math.MaxInt32,
expectSent: 0,
@@ -2554,7 +2554,7 @@ func TestWriteStats(t *testing.T) {
filter.Rules[ruleIdx].Matchers = []stack.Matcher{&limitedMatcher{nPackets - 1}}
// Make sure the next rule is ACCEPT.
filter.Rules[ruleIdx+1].Target = &stack.AcceptTarget{}
ipt.ForceReplaceTable(stack.FilterID, filter, true /* ipv6 */)
ipt.ReplaceTable(stack.FilterID, filter, true /* ipv6 */)
},
allowPackets: math.MaxInt32,
expectSent: nPackets - 1,
@@ -2574,7 +2574,7 @@ func TestWriteStats(t *testing.T) {
filter.Rules[ruleIdx].Matchers = []stack.Matcher{&limitedMatcher{nPackets - 1}}
// Make sure the next rule is ACCEPT.
filter.Rules[ruleIdx+1].Target = &stack.AcceptTarget{}
ipt.ForceReplaceTable(stack.NATID, filter, true /* ipv6 */)
ipt.ReplaceTable(stack.NATID, filter, true /* ipv6 */)
},
allowPackets: math.MaxInt32,
expectSent: nPackets - 1,
+24 -43
View File
@@ -17,7 +17,6 @@ package stack
import (
"fmt"
"math/rand"
"reflect"
"time"
"gvisor.dev/gvisor/pkg/tcpip"
@@ -49,11 +48,11 @@ func DefaultTables(clock tcpip.Clock, rand *rand.Rand) *IPTables {
v4Tables: [NumTables]Table{
NATID: {
Rules: []Rule{
{Filter: EmptyFilter4(), Target: &AcceptTarget{NetworkProtocol: header.IPv4ProtocolNumber}},
{Filter: EmptyFilter4(), Target: &AcceptTarget{NetworkProtocol: header.IPv4ProtocolNumber}},
{Filter: EmptyFilter4(), Target: &AcceptTarget{NetworkProtocol: header.IPv4ProtocolNumber}},
{Filter: EmptyFilter4(), Target: &AcceptTarget{NetworkProtocol: header.IPv4ProtocolNumber}},
{Filter: EmptyFilter4(), Target: &ErrorTarget{NetworkProtocol: header.IPv4ProtocolNumber}},
{Target: &AcceptTarget{NetworkProtocol: header.IPv4ProtocolNumber}},
{Target: &AcceptTarget{NetworkProtocol: header.IPv4ProtocolNumber}},
{Target: &AcceptTarget{NetworkProtocol: header.IPv4ProtocolNumber}},
{Target: &AcceptTarget{NetworkProtocol: header.IPv4ProtocolNumber}},
{Target: &ErrorTarget{NetworkProtocol: header.IPv4ProtocolNumber}},
},
BuiltinChains: [NumHooks]int{
Prerouting: 0,
@@ -72,9 +71,9 @@ func DefaultTables(clock tcpip.Clock, rand *rand.Rand) *IPTables {
},
MangleID: {
Rules: []Rule{
{Filter: EmptyFilter4(), Target: &AcceptTarget{NetworkProtocol: header.IPv4ProtocolNumber}},
{Filter: EmptyFilter4(), Target: &AcceptTarget{NetworkProtocol: header.IPv4ProtocolNumber}},
{Filter: EmptyFilter4(), Target: &ErrorTarget{NetworkProtocol: header.IPv4ProtocolNumber}},
{Target: &AcceptTarget{NetworkProtocol: header.IPv4ProtocolNumber}},
{Target: &AcceptTarget{NetworkProtocol: header.IPv4ProtocolNumber}},
{Target: &ErrorTarget{NetworkProtocol: header.IPv4ProtocolNumber}},
},
BuiltinChains: [NumHooks]int{
Prerouting: 0,
@@ -90,10 +89,10 @@ func DefaultTables(clock tcpip.Clock, rand *rand.Rand) *IPTables {
},
FilterID: {
Rules: []Rule{
{Filter: EmptyFilter4(), Target: &AcceptTarget{NetworkProtocol: header.IPv4ProtocolNumber}},
{Filter: EmptyFilter4(), Target: &AcceptTarget{NetworkProtocol: header.IPv4ProtocolNumber}},
{Filter: EmptyFilter4(), Target: &AcceptTarget{NetworkProtocol: header.IPv4ProtocolNumber}},
{Filter: EmptyFilter4(), Target: &ErrorTarget{NetworkProtocol: header.IPv4ProtocolNumber}},
{Target: &AcceptTarget{NetworkProtocol: header.IPv4ProtocolNumber}},
{Target: &AcceptTarget{NetworkProtocol: header.IPv4ProtocolNumber}},
{Target: &AcceptTarget{NetworkProtocol: header.IPv4ProtocolNumber}},
{Target: &ErrorTarget{NetworkProtocol: header.IPv4ProtocolNumber}},
},
BuiltinChains: [NumHooks]int{
Prerouting: HookUnset,
@@ -114,11 +113,11 @@ func DefaultTables(clock tcpip.Clock, rand *rand.Rand) *IPTables {
v6Tables: [NumTables]Table{
NATID: {
Rules: []Rule{
{Filter: EmptyFilter6(), Target: &AcceptTarget{NetworkProtocol: header.IPv6ProtocolNumber}},
{Filter: EmptyFilter6(), Target: &AcceptTarget{NetworkProtocol: header.IPv6ProtocolNumber}},
{Filter: EmptyFilter6(), Target: &AcceptTarget{NetworkProtocol: header.IPv6ProtocolNumber}},
{Filter: EmptyFilter6(), Target: &AcceptTarget{NetworkProtocol: header.IPv6ProtocolNumber}},
{Filter: EmptyFilter6(), Target: &ErrorTarget{NetworkProtocol: header.IPv6ProtocolNumber}},
{Target: &AcceptTarget{NetworkProtocol: header.IPv6ProtocolNumber}},
{Target: &AcceptTarget{NetworkProtocol: header.IPv6ProtocolNumber}},
{Target: &AcceptTarget{NetworkProtocol: header.IPv6ProtocolNumber}},
{Target: &AcceptTarget{NetworkProtocol: header.IPv6ProtocolNumber}},
{Target: &ErrorTarget{NetworkProtocol: header.IPv6ProtocolNumber}},
},
BuiltinChains: [NumHooks]int{
Prerouting: 0,
@@ -137,9 +136,9 @@ func DefaultTables(clock tcpip.Clock, rand *rand.Rand) *IPTables {
},
MangleID: {
Rules: []Rule{
{Filter: EmptyFilter6(), Target: &AcceptTarget{NetworkProtocol: header.IPv6ProtocolNumber}},
{Filter: EmptyFilter6(), Target: &AcceptTarget{NetworkProtocol: header.IPv6ProtocolNumber}},
{Filter: EmptyFilter6(), Target: &ErrorTarget{NetworkProtocol: header.IPv6ProtocolNumber}},
{Target: &AcceptTarget{NetworkProtocol: header.IPv6ProtocolNumber}},
{Target: &AcceptTarget{NetworkProtocol: header.IPv6ProtocolNumber}},
{Target: &ErrorTarget{NetworkProtocol: header.IPv6ProtocolNumber}},
},
BuiltinChains: [NumHooks]int{
Prerouting: 0,
@@ -155,10 +154,10 @@ func DefaultTables(clock tcpip.Clock, rand *rand.Rand) *IPTables {
},
FilterID: {
Rules: []Rule{
{Filter: EmptyFilter6(), Target: &AcceptTarget{NetworkProtocol: header.IPv6ProtocolNumber}},
{Filter: EmptyFilter6(), Target: &AcceptTarget{NetworkProtocol: header.IPv6ProtocolNumber}},
{Filter: EmptyFilter6(), Target: &AcceptTarget{NetworkProtocol: header.IPv6ProtocolNumber}},
{Filter: EmptyFilter6(), Target: &ErrorTarget{NetworkProtocol: header.IPv6ProtocolNumber}},
{Target: &AcceptTarget{NetworkProtocol: header.IPv6ProtocolNumber}},
{Target: &AcceptTarget{NetworkProtocol: header.IPv6ProtocolNumber}},
{Target: &AcceptTarget{NetworkProtocol: header.IPv6ProtocolNumber}},
{Target: &ErrorTarget{NetworkProtocol: header.IPv6ProtocolNumber}},
},
BuiltinChains: [NumHooks]int{
Prerouting: HookUnset,
@@ -233,29 +232,11 @@ func (it *IPTables) getTableRLocked(id TableID, ipv6 bool) Table {
// ReplaceTable replaces or inserts table by name. It panics when an invalid id
// is provided.
func (it *IPTables) ReplaceTable(id TableID, table Table, ipv6 bool) {
it.replaceTable(id, table, ipv6, false /* force */)
}
// ForceReplaceTable replaces or inserts table by name. It panics when an invalid id
// is provided. It enables iptables even when the inserted table is all
// conditionless ACCEPT, skipping our optimization that disables iptables until
// they're modified.
func (it *IPTables) ForceReplaceTable(id TableID, table Table, ipv6 bool) {
it.replaceTable(id, table, ipv6, true /* force */)
}
func (it *IPTables) replaceTable(id TableID, table Table, ipv6, force bool) {
it.mu.Lock()
defer it.mu.Unlock()
// If iptables is being enabled, initialize the conntrack table and
// reaper.
if !it.modified {
// Don't do anything if the table is identical.
if ((ipv6 && reflect.DeepEqual(table, it.v6Tables[id])) || (!ipv6 && reflect.DeepEqual(table, it.v4Tables[id]))) && !force {
return
}
it.connections.init()
it.startReaper(reaperDelay)
}
+1 -1
View File
@@ -300,7 +300,7 @@ func TestNATAlwaysPerformed(t *testing.T) {
iptables := DefaultTables(clock, rand.New(rand.NewSource(0 /* seed */)))
// Just to make sure the iptables is not short circuited.
iptables.ForceReplaceTable(NATID, iptables.GetTable(NATID, ipv6), ipv6)
iptables.ReplaceTable(NATID, iptables.GetTable(NATID, ipv6), ipv6)
pkt := v6PacketBuffer()
-28
View File
@@ -103,14 +103,6 @@ type IPTables struct {
modified bool
}
// Modified returns whether iptables has been modified. It is inherently racy
// and intended for use only in tests.
func (it *IPTables) Modified() bool {
it.mu.Lock()
defer it.mu.Unlock()
return it.modified
}
// VisitTargets traverses all the targets of all tables and replaces each with
// transform(target).
func (it *IPTables) VisitTargets(transform func(Target) Target) {
@@ -243,26 +235,6 @@ type IPHeaderFilter struct {
OutputInterfaceInvert bool
}
// EmptyFilter4 returns an initialized IPv4 header filter.
func EmptyFilter4() IPHeaderFilter {
return IPHeaderFilter{
Dst: tcpip.AddrFrom4([4]byte{}),
DstMask: tcpip.AddrFrom4([4]byte{}),
Src: tcpip.AddrFrom4([4]byte{}),
SrcMask: tcpip.AddrFrom4([4]byte{}),
}
}
// EmptyFilter6 returns an initialized IPv6 header filter.
func EmptyFilter6() IPHeaderFilter {
return IPHeaderFilter{
Dst: tcpip.AddrFrom16([16]byte{}),
DstMask: tcpip.AddrFrom16([16]byte{}),
Src: tcpip.AddrFrom16([16]byte{}),
SrcMask: tcpip.AddrFrom16([16]byte{}),
}
}
// match returns whether pkt matches the filter.
//
// Preconditions: pkt.NetworkHeader is set and is at least of the minimal IPv4
+18 -18
View File
@@ -189,7 +189,7 @@ func TestIPTablesStatsForInput(t *testing.T) {
filter.Rules[ruleIdx].Matchers = []stack.Matcher{&inputIfNameMatcher{nicName}}
// Make sure the packet is not dropped by the next rule.
filter.Rules[ruleIdx+1].Target = &stack.AcceptTarget{}
ipt.ForceReplaceTable(stack.FilterID, filter, true /* ipv6 */)
ipt.ReplaceTable(stack.FilterID, filter, true /* ipv6 */)
},
genPacket: genPacketV6,
proto: header.IPv6ProtocolNumber,
@@ -208,7 +208,7 @@ func TestIPTablesStatsForInput(t *testing.T) {
filter.Rules[ruleIdx].Target = &stack.DropTarget{}
filter.Rules[ruleIdx].Matchers = []stack.Matcher{&inputIfNameMatcher{nicName}}
filter.Rules[ruleIdx+1].Target = &stack.AcceptTarget{}
ipt.ForceReplaceTable(stack.FilterID, filter, false /* ipv6 */)
ipt.ReplaceTable(stack.FilterID, filter, false /* ipv6 */)
},
genPacket: genPacketV4,
proto: header.IPv4ProtocolNumber,
@@ -226,7 +226,7 @@ func TestIPTablesStatsForInput(t *testing.T) {
filter.Rules[ruleIdx].Filter = stack.IPHeaderFilter{InputInterface: anotherNicName}
filter.Rules[ruleIdx].Target = &stack.DropTarget{}
filter.Rules[ruleIdx+1].Target = &stack.AcceptTarget{}
ipt.ForceReplaceTable(stack.FilterID, filter, true /* ipv6 */)
ipt.ReplaceTable(stack.FilterID, filter, true /* ipv6 */)
},
genPacket: genPacketV6,
proto: header.IPv6ProtocolNumber,
@@ -244,7 +244,7 @@ func TestIPTablesStatsForInput(t *testing.T) {
filter.Rules[ruleIdx].Filter = stack.IPHeaderFilter{InputInterface: anotherNicName}
filter.Rules[ruleIdx].Target = &stack.DropTarget{}
filter.Rules[ruleIdx+1].Target = &stack.AcceptTarget{}
ipt.ForceReplaceTable(stack.FilterID, filter, false /* ipv6 */)
ipt.ReplaceTable(stack.FilterID, filter, false /* ipv6 */)
},
genPacket: genPacketV4,
proto: header.IPv4ProtocolNumber,
@@ -265,7 +265,7 @@ func TestIPTablesStatsForInput(t *testing.T) {
}
filter.Rules[ruleIdx].Target = &stack.DropTarget{}
filter.Rules[ruleIdx+1].Target = &stack.AcceptTarget{}
ipt.ForceReplaceTable(stack.FilterID, filter, true /* ipv6 */)
ipt.ReplaceTable(stack.FilterID, filter, true /* ipv6 */)
},
genPacket: genPacketV6,
proto: header.IPv6ProtocolNumber,
@@ -286,7 +286,7 @@ func TestIPTablesStatsForInput(t *testing.T) {
}
filter.Rules[ruleIdx].Target = &stack.DropTarget{}
filter.Rules[ruleIdx+1].Target = &stack.AcceptTarget{}
ipt.ForceReplaceTable(stack.FilterID, filter, false /* ipv6 */)
ipt.ReplaceTable(stack.FilterID, filter, false /* ipv6 */)
},
genPacket: genPacketV4,
proto: header.IPv4ProtocolNumber,
@@ -304,7 +304,7 @@ func TestIPTablesStatsForInput(t *testing.T) {
filter.Rules[ruleIdx].Target = &stack.DropTarget{}
filter.Rules[ruleIdx].Matchers = []stack.Matcher{&inputIfNameMatcher{anotherNicName}}
filter.Rules[ruleIdx+1].Target = &stack.AcceptTarget{}
ipt.ForceReplaceTable(stack.FilterID, filter, true /* ipv6 */)
ipt.ReplaceTable(stack.FilterID, filter, true /* ipv6 */)
},
genPacket: genPacketV6,
proto: header.IPv6ProtocolNumber,
@@ -322,7 +322,7 @@ func TestIPTablesStatsForInput(t *testing.T) {
filter.Rules[ruleIdx].Target = &stack.DropTarget{}
filter.Rules[ruleIdx].Matchers = []stack.Matcher{&inputIfNameMatcher{anotherNicName}}
filter.Rules[ruleIdx+1].Target = &stack.AcceptTarget{}
ipt.ForceReplaceTable(stack.FilterID, filter, false /* ipv6 */)
ipt.ReplaceTable(stack.FilterID, filter, false /* ipv6 */)
},
genPacket: genPacketV4,
proto: header.IPv4ProtocolNumber,
@@ -466,7 +466,7 @@ func TestIPTableWritePackets(t *testing.T) {
},
}
s.IPTables().ForceReplaceTable(stack.FilterID, table, false /* ipv4 */)
s.IPTables().ReplaceTable(stack.FilterID, table, false /* ipv4 */)
},
genPacket: func(r *stack.Route) stack.PacketBufferList {
var pkts stack.PacketBufferList
@@ -555,7 +555,7 @@ func TestIPTableWritePackets(t *testing.T) {
},
}
s.IPTables().ForceReplaceTable(stack.FilterID, table, true /* ipv6 */)
s.IPTables().ReplaceTable(stack.FilterID, table, true /* ipv6 */)
},
genPacket: func(r *stack.Route) stack.PacketBufferList {
var pkts stack.PacketBufferList
@@ -708,7 +708,7 @@ func setupDropFilter(hook stack.Hook, f stack.IPHeaderFilter) func(*testing.T, *
filter.Rules[ruleIdx].Target = &stack.DropTarget{NetworkProtocol: netProto}
// Make sure the packet is not dropped by the next rule.
filter.Rules[ruleIdx+1].Target = &stack.AcceptTarget{NetworkProtocol: netProto}
ipt.ForceReplaceTable(stack.FilterID, filter, ipv6)
ipt.ReplaceTable(stack.FilterID, filter, ipv6)
}
}
@@ -1216,7 +1216,7 @@ func setupNAT(t *testing.T, s *stack.Stack, netProto tcpip.NetworkProtocolNumber
table.Rules[ruleIdx].Target = target
// Make sure the packet is not dropped by the next rule.
table.Rules[ruleIdx+1].Target = &stack.AcceptTarget{}
ipt.ForceReplaceTable(stack.NATID, table, ipv6)
ipt.ReplaceTable(stack.NATID, table, ipv6)
}
func setupDNAT(t *testing.T, s *stack.Stack, netProto tcpip.NetworkProtocolNumber, transProto tcpip.TransportProtocolNumber, target stack.Target) {
@@ -1309,7 +1309,7 @@ func setupTwiceNAT(t *testing.T, s *stack.Stack, netProto tcpip.NetworkProtocolN
},
}
ipt.ForceReplaceTable(stack.NATID, table, ipv6)
ipt.ReplaceTable(stack.NATID, table, ipv6)
}
type natType struct {
@@ -2527,7 +2527,7 @@ func TestNATICMPError(t *testing.T) {
},
}
ipt.ForceReplaceTable(stack.NATID, table, ipv6)
ipt.ReplaceTable(stack.NATID, table, ipv6)
buf := transportType.buf
@@ -2898,7 +2898,7 @@ func TestSNATHandlePortOrIdentConflicts(t *testing.T) {
},
}
ipt.ForceReplaceTable(stack.NATID, table, ipv6)
ipt.ReplaceTable(stack.NATID, table, ipv6)
for i, srcAddr := range test.srcAddrs {
t.Run(fmt.Sprintf("Packet#%d", i), func(t *testing.T) {
@@ -2979,7 +2979,7 @@ func TestLocallyRoutedPackets(t *testing.T) {
ipv6 := test.netProto == ipv6.ProtocolNumber
ipt := s.IPTables()
filter := ipt.GetTable(stack.FilterID, ipv6)
ipt.ForceReplaceTable(stack.FilterID, filter, ipv6)
ipt.ReplaceTable(stack.FilterID, filter, ipv6)
}
var wq waiter.Queue
@@ -3303,7 +3303,7 @@ func TestRejectWith(t *testing.T) {
filter.Rules[ruleIdx].Target = test.rejectTarget(t, s.NetworkProtocolInstance(test.netProto), rejectWith.val)
// Make sure the packet is not dropped by the next rule.
filter.Rules[ruleIdx+1].Target = &stack.AcceptTarget{}
ipt.ForceReplaceTable(stack.FilterID, filter, ipv6)
ipt.ReplaceTable(stack.FilterID, filter, ipv6)
}
func() {
@@ -3405,7 +3405,7 @@ func TestInvalidTransportHeader(t *testing.T) {
// Enable iptables and conntrack.
ipt := s.IPTables()
filter := ipt.GetTable(stack.FilterID, false /* ipv6 */)
ipt.ForceReplaceTable(stack.FilterID, filter, false /* ipv6 */)
ipt.ReplaceTable(stack.FilterID, filter, false /* ipv6 */)
// This can panic if conntrack isn't checking lengths.
e.InjectInbound(header.IPv4ProtocolNumber, test.genPacket(test.offset))
+4
View File
@@ -330,6 +330,10 @@ type Config struct {
// explicitlySet contains whether a flag was explicitly set on the command-line from which this
// Config was constructed. Nil when the Config was not initialized from a FlagSet.
explicitlySet map[string]struct{}
// ScrapeNAT, when true, tells runsc to scrape the host network
// namespace's NAT iptables and reproduce it inside the sandbox.
ReproduceNAT bool `flag:"EXPERIMENTAL-reproduce-nat"`
}
func (c *Config) validate() error {
+7 -5
View File
@@ -120,6 +120,7 @@ func RegisterFlags(flagSet *flag.FlagSet) {
flagSet.Int("num-network-channels", 1, "number of underlying channels(FDs) to use for network link endpoints.")
flagSet.Bool("buffer-pooling", true, "enable allocation of buffers from a shared pool instead of the heap.")
flagSet.Bool("EXPERIMENTAL-afxdp", false, "EXPERIMENTAL. Use an AF_XDP socket to receive packets.")
flagSet.Bool("EXPERIMENTAL-reproduce-nat", false, "EXPERIMENTAL. Scrape the host netns NAT table and reproduce it in the sandbox.")
// Flags that control sandbox runtime behavior: accelerator related.
flagSet.Bool("nvproxy", false, "EXPERIMENTAL: enable support for Nvidia GPUs")
@@ -140,11 +141,12 @@ func RegisterFlags(flagSet *flag.FlagSet) {
var overrideAllowlist = map[string]struct {
check func(name string, value string) error
}{
"debug": {},
"strace": {},
"strace-syscalls": {},
"strace-log-size": {},
"host-uds": {},
"debug": {},
"strace": {},
"strace-syscalls": {},
"strace-log-size": {},
"host-uds": {},
"EXPERIMENTAL-reproduce-nat": {},
"oci-seccomp": {check: checkOciSeccomp},
}
+6 -7
View File
@@ -319,14 +319,13 @@ func createInterfacesAndRoutesFromNS(conn *urpc.Client, nsPath string, conf *con
args.FilePayload.Files = append(args.FilePayload.Files, pcap)
}
// Pass the host's NAT table.
f, err := writeNATBlob()
if err != nil {
// We warn rather than error because not every kernel has
// iptables enabled.
log.Warningf("failed to write NAT blob: %v", err)
} else {
// Pass the host's NAT table if requested.
if conf.ReproduceNAT {
args.NATBlob = true
f, err := writeNATBlob()
if err != nil {
return fmt.Errorf("failed to write NAT blob: %v", err)
}
args.FilePayload.Files = append(args.FilePayload.Files, f)
}