mirror of
https://github.com/netbirdio/gvisor.git
synced 2026-05-22 17:12:49 -07:00
Automated rollback of changelist 580051079
PiperOrigin-RevId: 580649803
This commit is contained in:
committed by
gVisor bot
parent
9284335c9d
commit
40ee36ac4c
@@ -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.
+13
-42
@@ -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")
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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
@@ -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)
|
||||
}
|
||||
|
||||
@@ -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()
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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))
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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},
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user