ip6tables: redirect support
Adds support for the IPv6-compatible redirect target. Redirection is a limited form of DNAT, where the destination is always the localhost. Updates #3549. PiperOrigin-RevId: 334698344
This commit is contained in:
parent
7f9e13053e
commit
6f8d64f422
|
@ -321,3 +321,16 @@ const (
|
|||
// Enable all flags.
|
||||
IP6T_INV_MASK = 0x7F
|
||||
)
|
||||
|
||||
// NFNATRange corresponds to struct nf_nat_range in
|
||||
// include/uapi/linux/netfilter/nf_nat.h.
|
||||
type NFNATRange struct {
|
||||
Flags uint32
|
||||
MinAddr Inet6Addr
|
||||
MaxAddr Inet6Addr
|
||||
MinProto uint16 // Network byte order.
|
||||
MaxProto uint16 // Network byte order.
|
||||
}
|
||||
|
||||
// SizeOfNFNATRange is the size of NFNATRange.
|
||||
const SizeOfNFNATRange = 40
|
||||
|
|
|
@ -147,10 +147,6 @@ func SetEntries(stk *stack.Stack, optVal []byte, ipv6 bool) *syserr.Error {
|
|||
case stack.FilterTable:
|
||||
table = stack.EmptyFilterTable()
|
||||
case stack.NATTable:
|
||||
if ipv6 {
|
||||
nflog("IPv6 redirection not yet supported (gvisor.dev/issue/3549)")
|
||||
return syserr.ErrInvalidArgument
|
||||
}
|
||||
table = stack.EmptyNATTable()
|
||||
default:
|
||||
nflog("we don't yet support writing to the %q table (gvisor.dev/issue/170)", replace.Name.String())
|
||||
|
|
|
@ -47,6 +47,9 @@ func init() {
|
|||
registerTargetMaker(&redirectTargetMaker{
|
||||
NetworkProtocol: header.IPv4ProtocolNumber,
|
||||
})
|
||||
registerTargetMaker(&nfNATTargetMaker{
|
||||
NetworkProtocol: header.IPv6ProtocolNumber,
|
||||
})
|
||||
}
|
||||
|
||||
type standardTargetMaker struct {
|
||||
|
@ -250,6 +253,86 @@ func (*redirectTargetMaker) unmarshal(buf []byte, filter stack.IPHeaderFilter) (
|
|||
return &target, nil
|
||||
}
|
||||
|
||||
type nfNATTarget struct {
|
||||
Target linux.XTEntryTarget
|
||||
Range linux.NFNATRange
|
||||
}
|
||||
|
||||
const nfNATMarhsalledSize = linux.SizeOfXTEntryTarget + linux.SizeOfNFNATRange
|
||||
|
||||
type nfNATTargetMaker struct {
|
||||
NetworkProtocol tcpip.NetworkProtocolNumber
|
||||
}
|
||||
|
||||
func (rm *nfNATTargetMaker) id() stack.TargetID {
|
||||
return stack.TargetID{
|
||||
Name: stack.RedirectTargetName,
|
||||
NetworkProtocol: rm.NetworkProtocol,
|
||||
}
|
||||
}
|
||||
|
||||
func (*nfNATTargetMaker) marshal(target stack.Target) []byte {
|
||||
rt := target.(*stack.RedirectTarget)
|
||||
nt := nfNATTarget{
|
||||
Target: linux.XTEntryTarget{
|
||||
TargetSize: nfNATMarhsalledSize,
|
||||
},
|
||||
Range: linux.NFNATRange{
|
||||
Flags: linux.NF_NAT_RANGE_PROTO_SPECIFIED,
|
||||
},
|
||||
}
|
||||
copy(nt.Target.Name[:], stack.RedirectTargetName)
|
||||
copy(nt.Range.MinAddr[:], rt.Addr)
|
||||
copy(nt.Range.MaxAddr[:], rt.Addr)
|
||||
|
||||
nt.Range.MinProto = htons(rt.Port)
|
||||
nt.Range.MaxProto = nt.Range.MinProto
|
||||
|
||||
ret := make([]byte, 0, nfNATMarhsalledSize)
|
||||
return binary.Marshal(ret, usermem.ByteOrder, nt)
|
||||
}
|
||||
|
||||
func (*nfNATTargetMaker) unmarshal(buf []byte, filter stack.IPHeaderFilter) (stack.Target, *syserr.Error) {
|
||||
if size := nfNATMarhsalledSize; len(buf) < size {
|
||||
nflog("nfNATTargetMaker: buf has insufficient size (%d) for nfNAT target (%d)", len(buf), size)
|
||||
return nil, syserr.ErrInvalidArgument
|
||||
}
|
||||
|
||||
if p := filter.Protocol; p != header.TCPProtocolNumber && p != header.UDPProtocolNumber {
|
||||
nflog("nfNATTargetMaker: bad proto %d", p)
|
||||
return nil, syserr.ErrInvalidArgument
|
||||
}
|
||||
|
||||
var natRange linux.NFNATRange
|
||||
buf = buf[linux.SizeOfXTEntryTarget:nfNATMarhsalledSize]
|
||||
binary.Unmarshal(buf, usermem.ByteOrder, &natRange)
|
||||
|
||||
// We don't support port or address ranges.
|
||||
if natRange.MinAddr != natRange.MaxAddr {
|
||||
nflog("nfNATTargetMaker: MinAddr and MaxAddr are different")
|
||||
return nil, syserr.ErrInvalidArgument
|
||||
}
|
||||
if natRange.MinProto != natRange.MaxProto {
|
||||
nflog("nfNATTargetMaker: MinProto and MaxProto are different")
|
||||
return nil, syserr.ErrInvalidArgument
|
||||
}
|
||||
|
||||
// TODO(gvisor.dev/issue/3549): Check for other flags.
|
||||
// For now, redirect target only supports destination change.
|
||||
if natRange.Flags != linux.NF_NAT_RANGE_PROTO_SPECIFIED {
|
||||
nflog("nfNATTargetMaker: invalid range flags %d", natRange.Flags)
|
||||
return nil, syserr.ErrInvalidArgument
|
||||
}
|
||||
|
||||
target := stack.RedirectTarget{
|
||||
NetworkProtocol: filter.NetworkProtocol(),
|
||||
Addr: tcpip.Address(natRange.MinAddr[:]),
|
||||
Port: ntohs(natRange.MinProto),
|
||||
}
|
||||
|
||||
return &target, nil
|
||||
}
|
||||
|
||||
// translateToStandardTarget translates from the value in a
|
||||
// linux.XTStandardTarget to an stack.Verdict.
|
||||
func translateToStandardTarget(val int32, netProto tcpip.NetworkProtocolNumber) (stack.Target, *syserr.Error) {
|
||||
|
|
|
@ -1512,8 +1512,17 @@ func getSockOptIPv6(t *kernel.Task, s socket.SocketOps, ep commonEndpoint, name
|
|||
return &vP, nil
|
||||
|
||||
case linux.IP6T_ORIGINAL_DST:
|
||||
// TODO(gvisor.dev/issue/170): ip6tables.
|
||||
return nil, syserr.ErrInvalidArgument
|
||||
if outLen < int(binary.Size(linux.SockAddrInet6{})) {
|
||||
return nil, syserr.ErrInvalidArgument
|
||||
}
|
||||
|
||||
var v tcpip.OriginalDestinationOption
|
||||
if err := ep.GetSockOpt(&v); err != nil {
|
||||
return nil, syserr.TranslateNetstackError(err)
|
||||
}
|
||||
|
||||
a, _ := ConvertAddress(linux.AF_INET6, tcpip.FullAddress(v))
|
||||
return a.(*linux.SockAddrInet6), nil
|
||||
|
||||
case linux.IP6T_SO_GET_INFO:
|
||||
if outLen < linux.SizeOfIPTGetinfo {
|
||||
|
@ -1555,6 +1564,26 @@ func getSockOptIPv6(t *kernel.Task, s socket.SocketOps, ep commonEndpoint, name
|
|||
}
|
||||
return &entries, nil
|
||||
|
||||
case linux.IP6T_SO_GET_REVISION_TARGET:
|
||||
if outLen < linux.SizeOfXTGetRevision {
|
||||
return nil, syserr.ErrInvalidArgument
|
||||
}
|
||||
|
||||
// Only valid for raw IPv6 sockets.
|
||||
if family, skType, _ := s.Type(); family != linux.AF_INET6 || skType != linux.SOCK_RAW {
|
||||
return nil, syserr.ErrProtocolNotAvailable
|
||||
}
|
||||
|
||||
stack := inet.StackFromContext(t)
|
||||
if stack == nil {
|
||||
return nil, syserr.ErrNoDevice
|
||||
}
|
||||
ret, err := netfilter.TargetRevision(t, outPtr, header.IPv6ProtocolNumber)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &ret, nil
|
||||
|
||||
default:
|
||||
emitUnimplementedEventIPv6(t, name)
|
||||
}
|
||||
|
|
|
@ -196,13 +196,14 @@ type bucket struct {
|
|||
|
||||
// packetToTupleID converts packet to a tuple ID. It fails when pkt lacks a valid
|
||||
// TCP header.
|
||||
//
|
||||
// Preconditions: pkt.NetworkHeader() is valid.
|
||||
func packetToTupleID(pkt *PacketBuffer) (tupleID, *tcpip.Error) {
|
||||
// TODO(gvisor.dev/issue/170): Need to support for other
|
||||
// protocols as well.
|
||||
netHeader := header.IPv4(pkt.NetworkHeader().View())
|
||||
if len(netHeader) < header.IPv4MinimumSize || netHeader.TransportProtocol() != header.TCPProtocolNumber {
|
||||
netHeader := pkt.Network()
|
||||
if netHeader.TransportProtocol() != header.TCPProtocolNumber {
|
||||
return tupleID{}, tcpip.ErrUnknownProtocol
|
||||
}
|
||||
|
||||
tcpHeader := header.TCP(pkt.TransportHeader().View())
|
||||
if len(tcpHeader) < header.TCPMinimumSize {
|
||||
return tupleID{}, tcpip.ErrUnknownProtocol
|
||||
|
@ -214,7 +215,7 @@ func packetToTupleID(pkt *PacketBuffer) (tupleID, *tcpip.Error) {
|
|||
dstAddr: netHeader.DestinationAddress(),
|
||||
dstPort: tcpHeader.DestinationPort(),
|
||||
transProto: netHeader.TransportProtocol(),
|
||||
netProto: header.IPv4ProtocolNumber,
|
||||
netProto: pkt.NetworkProtocolNumber,
|
||||
}, nil
|
||||
}
|
||||
|
||||
|
@ -344,7 +345,7 @@ func handlePacketPrerouting(pkt *PacketBuffer, conn *conn, dir direction) {
|
|||
return
|
||||
}
|
||||
|
||||
netHeader := header.IPv4(pkt.NetworkHeader().View())
|
||||
netHeader := pkt.Network()
|
||||
tcpHeader := header.TCP(pkt.TransportHeader().View())
|
||||
|
||||
// For prerouting redirection, packets going in the original direction
|
||||
|
@ -366,8 +367,12 @@ func handlePacketPrerouting(pkt *PacketBuffer, conn *conn, dir direction) {
|
|||
// support cases when they are validated, e.g. when we can't offload
|
||||
// receive checksumming.
|
||||
|
||||
netHeader.SetChecksum(0)
|
||||
netHeader.SetChecksum(^netHeader.CalculateChecksum())
|
||||
// After modification, IPv4 packets need a valid checksum.
|
||||
if pkt.NetworkProtocolNumber == header.IPv4ProtocolNumber {
|
||||
netHeader := header.IPv4(pkt.NetworkHeader().View())
|
||||
netHeader.SetChecksum(0)
|
||||
netHeader.SetChecksum(^netHeader.CalculateChecksum())
|
||||
}
|
||||
}
|
||||
|
||||
// handlePacketOutput manipulates ports for packets in Output hook.
|
||||
|
@ -377,7 +382,7 @@ func handlePacketOutput(pkt *PacketBuffer, conn *conn, gso *GSO, r *Route, dir d
|
|||
return
|
||||
}
|
||||
|
||||
netHeader := header.IPv4(pkt.NetworkHeader().View())
|
||||
netHeader := pkt.Network()
|
||||
tcpHeader := header.TCP(pkt.TransportHeader().View())
|
||||
|
||||
// For output redirection, packets going in the original direction
|
||||
|
@ -396,7 +401,7 @@ func handlePacketOutput(pkt *PacketBuffer, conn *conn, gso *GSO, r *Route, dir d
|
|||
|
||||
// Calculate the TCP checksum and set it.
|
||||
tcpHeader.SetChecksum(0)
|
||||
length := uint16(pkt.Size()) - uint16(netHeader.HeaderLength())
|
||||
length := uint16(pkt.Size()) - uint16(len(pkt.NetworkHeader().View()))
|
||||
xsum := r.PseudoHeaderChecksum(header.TCPProtocolNumber, length)
|
||||
if gso != nil && gso.NeedsCsum {
|
||||
tcpHeader.SetChecksum(xsum)
|
||||
|
@ -405,8 +410,11 @@ func handlePacketOutput(pkt *PacketBuffer, conn *conn, gso *GSO, r *Route, dir d
|
|||
tcpHeader.SetChecksum(^tcpHeader.CalculateChecksum(xsum))
|
||||
}
|
||||
|
||||
netHeader.SetChecksum(0)
|
||||
netHeader.SetChecksum(^netHeader.CalculateChecksum())
|
||||
if pkt.NetworkProtocolNumber == header.IPv4ProtocolNumber {
|
||||
netHeader := header.IPv4(pkt.NetworkHeader().View())
|
||||
netHeader.SetChecksum(0)
|
||||
netHeader.SetChecksum(^netHeader.CalculateChecksum())
|
||||
}
|
||||
}
|
||||
|
||||
// handlePacket will manipulate the port and address of the packet if the
|
||||
|
@ -422,7 +430,7 @@ func (ct *ConnTrack) handlePacket(pkt *PacketBuffer, hook Hook, gso *GSO, r *Rou
|
|||
}
|
||||
|
||||
// TODO(gvisor.dev/issue/170): Support other transport protocols.
|
||||
if nh := pkt.NetworkHeader().View(); nh.IsEmpty() || header.IPv4(nh).TransportProtocol() != header.TCPProtocolNumber {
|
||||
if pkt.Network().TransportProtocol() != header.TCPProtocolNumber {
|
||||
return false
|
||||
}
|
||||
|
||||
|
@ -473,7 +481,7 @@ func (ct *ConnTrack) maybeInsertNoop(pkt *PacketBuffer, hook Hook) {
|
|||
}
|
||||
|
||||
// We only track TCP connections.
|
||||
if nh := pkt.NetworkHeader().View(); nh.IsEmpty() || header.IPv4(nh).TransportProtocol() != header.TCPProtocolNumber {
|
||||
if pkt.Network().TransportProtocol() != header.TCPProtocolNumber {
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -609,7 +617,7 @@ func (ct *ConnTrack) reapTupleLocked(tuple *tuple, bucket int, now time.Time) bo
|
|||
return true
|
||||
}
|
||||
|
||||
func (ct *ConnTrack) originalDst(epID TransportEndpointID) (tcpip.Address, uint16, *tcpip.Error) {
|
||||
func (ct *ConnTrack) originalDst(epID TransportEndpointID, netProto tcpip.NetworkProtocolNumber) (tcpip.Address, uint16, *tcpip.Error) {
|
||||
// Lookup the connection. The reply's original destination
|
||||
// describes the original address.
|
||||
tid := tupleID{
|
||||
|
@ -618,7 +626,7 @@ func (ct *ConnTrack) originalDst(epID TransportEndpointID) (tcpip.Address, uint1
|
|||
dstAddr: epID.RemoteAddress,
|
||||
dstPort: epID.RemotePort,
|
||||
transProto: header.TCPProtocolNumber,
|
||||
netProto: header.IPv4ProtocolNumber,
|
||||
netProto: netProto,
|
||||
}
|
||||
conn, _ := ct.connForTID(tid)
|
||||
if conn == nil {
|
||||
|
|
|
@ -502,11 +502,11 @@ func (it *IPTables) checkRule(hook Hook, pkt *PacketBuffer, table Table, ruleIdx
|
|||
|
||||
// OriginalDst returns the original destination of redirected connections. It
|
||||
// returns an error if the connection doesn't exist or isn't redirected.
|
||||
func (it *IPTables) OriginalDst(epID TransportEndpointID) (tcpip.Address, uint16, *tcpip.Error) {
|
||||
func (it *IPTables) OriginalDst(epID TransportEndpointID, netProto tcpip.NetworkProtocolNumber) (tcpip.Address, uint16, *tcpip.Error) {
|
||||
it.mu.RLock()
|
||||
defer it.mu.RUnlock()
|
||||
if !it.modified {
|
||||
return "", 0, tcpip.ErrNotConnected
|
||||
}
|
||||
return it.connections.originalDst(epID)
|
||||
return it.connections.originalDst(epID, netProto)
|
||||
}
|
||||
|
|
|
@ -164,11 +164,15 @@ func (rt *RedirectTarget) Action(pkt *PacketBuffer, ct *ConnTrack, hook Hook, gs
|
|||
return RuleDrop, 0
|
||||
}
|
||||
|
||||
// Change the address to localhost (127.0.0.1) in Output and
|
||||
// to primary address of the incoming interface in Prerouting.
|
||||
// Change the address to localhost (127.0.0.1 or ::1) in Output and to
|
||||
// the primary address of the incoming interface in Prerouting.
|
||||
switch hook {
|
||||
case Output:
|
||||
rt.Addr = tcpip.Address([]byte{127, 0, 0, 1})
|
||||
if pkt.NetworkProtocolNumber == header.IPv4ProtocolNumber {
|
||||
rt.Addr = tcpip.Address([]byte{127, 0, 0, 1})
|
||||
} else {
|
||||
rt.Addr = header.IPv6Loopback
|
||||
}
|
||||
case Prerouting:
|
||||
rt.Addr = address
|
||||
default:
|
||||
|
@ -177,8 +181,7 @@ func (rt *RedirectTarget) Action(pkt *PacketBuffer, ct *ConnTrack, hook Hook, gs
|
|||
|
||||
// TODO(gvisor.dev/issue/170): Check Flags in RedirectTarget if
|
||||
// we need to change dest address (for OUTPUT chain) or ports.
|
||||
netHeader := header.IPv4(pkt.NetworkHeader().View())
|
||||
switch protocol := netHeader.TransportProtocol(); protocol {
|
||||
switch protocol := pkt.TransportProtocolNumber; protocol {
|
||||
case header.UDPProtocolNumber:
|
||||
udpHeader := header.UDP(pkt.TransportHeader().View())
|
||||
udpHeader.SetDestinationPort(rt.Port)
|
||||
|
@ -186,10 +189,10 @@ func (rt *RedirectTarget) Action(pkt *PacketBuffer, ct *ConnTrack, hook Hook, gs
|
|||
// Calculate UDP checksum and set it.
|
||||
if hook == Output {
|
||||
udpHeader.SetChecksum(0)
|
||||
length := uint16(pkt.Size()) - uint16(netHeader.HeaderLength())
|
||||
|
||||
// Only calculate the checksum if offloading isn't supported.
|
||||
if r.Capabilities()&CapabilityTXChecksumOffload == 0 {
|
||||
length := uint16(pkt.Size()) - uint16(len(pkt.NetworkHeader().View()))
|
||||
xsum := r.PseudoHeaderChecksum(protocol, length)
|
||||
for _, v := range pkt.Data.Views() {
|
||||
xsum = header.Checksum(v, xsum)
|
||||
|
@ -198,10 +201,15 @@ func (rt *RedirectTarget) Action(pkt *PacketBuffer, ct *ConnTrack, hook Hook, gs
|
|||
udpHeader.SetChecksum(^udpHeader.CalculateChecksum(xsum))
|
||||
}
|
||||
}
|
||||
// Change destination address.
|
||||
netHeader.SetDestinationAddress(rt.Addr)
|
||||
netHeader.SetChecksum(0)
|
||||
netHeader.SetChecksum(^netHeader.CalculateChecksum())
|
||||
|
||||
pkt.Network().SetDestinationAddress(rt.Addr)
|
||||
|
||||
// After modification, IPv4 packets need a valid checksum.
|
||||
if pkt.NetworkProtocolNumber == header.IPv4ProtocolNumber {
|
||||
netHeader := header.IPv4(pkt.NetworkHeader().View())
|
||||
netHeader.SetChecksum(0)
|
||||
netHeader.SetChecksum(^netHeader.CalculateChecksum())
|
||||
}
|
||||
pkt.NatDone = true
|
||||
case header.TCPProtocolNumber:
|
||||
if ct == nil {
|
||||
|
|
|
@ -19,6 +19,7 @@ import (
|
|||
"gvisor.dev/gvisor/pkg/sync"
|
||||
"gvisor.dev/gvisor/pkg/tcpip"
|
||||
"gvisor.dev/gvisor/pkg/tcpip/buffer"
|
||||
"gvisor.dev/gvisor/pkg/tcpip/header"
|
||||
)
|
||||
|
||||
type headerType int
|
||||
|
@ -255,6 +256,20 @@ func (pk *PacketBuffer) Clone() *PacketBuffer {
|
|||
return newPk
|
||||
}
|
||||
|
||||
// Network returns the network header as a header.Network.
|
||||
//
|
||||
// Network should only be called when NetworkHeader has been set.
|
||||
func (pk *PacketBuffer) Network() header.Network {
|
||||
switch netProto := pk.NetworkProtocolNumber; netProto {
|
||||
case header.IPv4ProtocolNumber:
|
||||
return header.IPv4(pk.NetworkHeader().View())
|
||||
case header.IPv6ProtocolNumber:
|
||||
return header.IPv6(pk.NetworkHeader().View())
|
||||
default:
|
||||
panic(fmt.Sprintf("unknown network protocol number %d", netProto))
|
||||
}
|
||||
}
|
||||
|
||||
// headerInfo stores metadata about a header in a packet.
|
||||
type headerInfo struct {
|
||||
// buf is the memorized slice for both prepended and consumed header.
|
||||
|
|
|
@ -2099,7 +2099,7 @@ func (e *endpoint) GetSockOpt(opt tcpip.GettableSocketOption) *tcpip.Error {
|
|||
case *tcpip.OriginalDestinationOption:
|
||||
e.LockUser()
|
||||
ipt := e.stack.IPTables()
|
||||
addr, port, err := ipt.OriginalDst(e.ID)
|
||||
addr, port, err := ipt.OriginalDst(e.ID, e.NetProto)
|
||||
e.UnlockUser()
|
||||
if err != nil {
|
||||
return err
|
||||
|
|
|
@ -48,13 +48,6 @@ func singleTest(t *testing.T, test TestCase) {
|
|||
}
|
||||
}
|
||||
|
||||
// TODO(gvisor.dev/issue/3549): IPv6 NAT support.
|
||||
func ipv4Test(t *testing.T, test TestCase) {
|
||||
t.Run("IPv4", func(t *testing.T) {
|
||||
iptablesTest(t, test, false)
|
||||
})
|
||||
}
|
||||
|
||||
func iptablesTest(t *testing.T, test TestCase, ipv6 bool) {
|
||||
if _, ok := Tests[test.Name()]; !ok {
|
||||
t.Fatalf("no test found with name %q. Has it been registered?", test.Name())
|
||||
|
@ -325,66 +318,66 @@ func TestFilterOutputInvertDestination(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestNATPreRedirectUDPPort(t *testing.T) {
|
||||
ipv4Test(t, NATPreRedirectUDPPort{})
|
||||
singleTest(t, NATPreRedirectUDPPort{})
|
||||
}
|
||||
|
||||
func TestNATPreRedirectTCPPort(t *testing.T) {
|
||||
ipv4Test(t, NATPreRedirectTCPPort{})
|
||||
singleTest(t, NATPreRedirectTCPPort{})
|
||||
}
|
||||
|
||||
func TestNATPreRedirectTCPOutgoing(t *testing.T) {
|
||||
ipv4Test(t, NATPreRedirectTCPOutgoing{})
|
||||
singleTest(t, NATPreRedirectTCPOutgoing{})
|
||||
}
|
||||
|
||||
func TestNATOutRedirectTCPIncoming(t *testing.T) {
|
||||
ipv4Test(t, NATOutRedirectTCPIncoming{})
|
||||
singleTest(t, NATOutRedirectTCPIncoming{})
|
||||
}
|
||||
func TestNATOutRedirectUDPPort(t *testing.T) {
|
||||
ipv4Test(t, NATOutRedirectUDPPort{})
|
||||
singleTest(t, NATOutRedirectUDPPort{})
|
||||
}
|
||||
|
||||
func TestNATOutRedirectTCPPort(t *testing.T) {
|
||||
ipv4Test(t, NATOutRedirectTCPPort{})
|
||||
singleTest(t, NATOutRedirectTCPPort{})
|
||||
}
|
||||
|
||||
func TestNATDropUDP(t *testing.T) {
|
||||
ipv4Test(t, NATDropUDP{})
|
||||
singleTest(t, NATDropUDP{})
|
||||
}
|
||||
|
||||
func TestNATAcceptAll(t *testing.T) {
|
||||
ipv4Test(t, NATAcceptAll{})
|
||||
singleTest(t, NATAcceptAll{})
|
||||
}
|
||||
|
||||
func TestNATOutRedirectIP(t *testing.T) {
|
||||
ipv4Test(t, NATOutRedirectIP{})
|
||||
singleTest(t, NATOutRedirectIP{})
|
||||
}
|
||||
|
||||
func TestNATOutDontRedirectIP(t *testing.T) {
|
||||
ipv4Test(t, NATOutDontRedirectIP{})
|
||||
singleTest(t, NATOutDontRedirectIP{})
|
||||
}
|
||||
|
||||
func TestNATOutRedirectInvert(t *testing.T) {
|
||||
ipv4Test(t, NATOutRedirectInvert{})
|
||||
singleTest(t, NATOutRedirectInvert{})
|
||||
}
|
||||
|
||||
func TestNATPreRedirectIP(t *testing.T) {
|
||||
ipv4Test(t, NATPreRedirectIP{})
|
||||
singleTest(t, NATPreRedirectIP{})
|
||||
}
|
||||
|
||||
func TestNATPreDontRedirectIP(t *testing.T) {
|
||||
ipv4Test(t, NATPreDontRedirectIP{})
|
||||
singleTest(t, NATPreDontRedirectIP{})
|
||||
}
|
||||
|
||||
func TestNATPreRedirectInvert(t *testing.T) {
|
||||
ipv4Test(t, NATPreRedirectInvert{})
|
||||
singleTest(t, NATPreRedirectInvert{})
|
||||
}
|
||||
|
||||
func TestNATRedirectRequiresProtocol(t *testing.T) {
|
||||
ipv4Test(t, NATRedirectRequiresProtocol{})
|
||||
singleTest(t, NATRedirectRequiresProtocol{})
|
||||
}
|
||||
|
||||
func TestNATLoopbackSkipsPrerouting(t *testing.T) {
|
||||
ipv4Test(t, NATLoopbackSkipsPrerouting{})
|
||||
singleTest(t, NATLoopbackSkipsPrerouting{})
|
||||
}
|
||||
|
||||
func TestInputSource(t *testing.T) {
|
||||
|
@ -421,9 +414,9 @@ func TestFilterAddrs(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestNATPreOriginalDst(t *testing.T) {
|
||||
ipv4Test(t, NATPreOriginalDst{})
|
||||
singleTest(t, NATPreOriginalDst{})
|
||||
}
|
||||
|
||||
func TestNATOutOriginalDst(t *testing.T) {
|
||||
ipv4Test(t, NATOutOriginalDst{})
|
||||
singleTest(t, NATOutOriginalDst{})
|
||||
}
|
||||
|
|
|
@ -95,16 +95,10 @@ TEST(IP6TablesBasic, GetRevision) {
|
|||
};
|
||||
socklen_t rev_len = sizeof(rev);
|
||||
|
||||
// TODO(gvisor.dev/issue/3549): IPv6 redirect support.
|
||||
const int retval =
|
||||
getsockopt(sock, SOL_IPV6, IP6T_SO_GET_REVISION_TARGET, &rev, &rev_len);
|
||||
if (IsRunningOnGvisor()) {
|
||||
EXPECT_THAT(retval, SyscallFailsWithErrno(ENOPROTOOPT));
|
||||
return;
|
||||
}
|
||||
|
||||
// Revision 0 exists.
|
||||
EXPECT_THAT(retval, SyscallSucceeds());
|
||||
EXPECT_THAT(
|
||||
getsockopt(sock, SOL_IPV6, IP6T_SO_GET_REVISION_TARGET, &rev, &rev_len),
|
||||
SyscallSucceeds());
|
||||
EXPECT_EQ(rev.revision, 0);
|
||||
|
||||
// Revisions > 0 don't exist.
|
||||
|
|
Loading…
Reference in New Issue