mirror of
https://github.com/netbirdio/gvisor.git
synced 2026-05-22 17:12:49 -07:00
netstack: iptables DNAT revision 1 support
PiperOrigin-RevId: 581537255
This commit is contained in:
committed by
gVisor bot
parent
62175dea49
commit
a69a4835f2
@@ -15,6 +15,8 @@
|
||||
package netfilter
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"gvisor.dev/gvisor/pkg/abi/linux"
|
||||
"gvisor.dev/gvisor/pkg/marshal"
|
||||
"gvisor.dev/gvisor/pkg/syserr"
|
||||
@@ -116,3 +118,82 @@ func (*dnatTargetMakerV4) unmarshal(buf []byte, filter stack.IPHeaderFilter) (ta
|
||||
|
||||
return &target, nil
|
||||
}
|
||||
|
||||
type dnatTargetMakerR1 struct {
|
||||
NetworkProtocol tcpip.NetworkProtocolNumber
|
||||
}
|
||||
|
||||
func (st *dnatTargetMakerR1) id() targetID {
|
||||
return targetID{
|
||||
name: DNATTargetName,
|
||||
networkProtocol: st.NetworkProtocol,
|
||||
revision: 1,
|
||||
}
|
||||
}
|
||||
|
||||
func (*dnatTargetMakerR1) marshal(target target) []byte {
|
||||
st := target.(*dnatTarget)
|
||||
nt := linux.XTNATTargetV1{
|
||||
Target: linux.XTEntryTarget{
|
||||
TargetSize: linux.SizeOfXTNATTargetV1,
|
||||
},
|
||||
Range: linux.NFNATRange{
|
||||
Flags: linux.NF_NAT_RANGE_MAP_IPS | linux.NF_NAT_RANGE_PROTO_SPECIFIED,
|
||||
},
|
||||
}
|
||||
copy(nt.Target.Name[:], DNATTargetName)
|
||||
copy(nt.Range.MinAddr[:], st.Addr.AsSlice())
|
||||
copy(nt.Range.MaxAddr[:], st.Addr.AsSlice())
|
||||
nt.Range.MinProto = htons(st.Port)
|
||||
nt.Range.MaxProto = nt.Range.MinProto
|
||||
|
||||
return marshal.Marshal(&nt)
|
||||
}
|
||||
|
||||
func (st *dnatTargetMakerR1) unmarshal(buf []byte, filter stack.IPHeaderFilter) (target, *syserr.Error) {
|
||||
if size := linux.SizeOfXTNATTargetV1; len(buf) < size {
|
||||
nflog("dnatTargetMakerR1: buf has insufficient size (%d) for DNAT target (%d)", len(buf), size)
|
||||
return nil, syserr.ErrInvalidArgument
|
||||
}
|
||||
|
||||
if p := filter.Protocol; p != header.TCPProtocolNumber && p != header.UDPProtocolNumber {
|
||||
nflog("dnatTargetMakerR1: bad proto %d", p)
|
||||
return nil, syserr.ErrInvalidArgument
|
||||
}
|
||||
|
||||
var natRange linux.NFNATRange
|
||||
natRange.UnmarshalUnsafe(buf[linux.SizeOfXTEntryTarget:])
|
||||
|
||||
// TODO(gvisor.dev/issue/5697): Support port or address ranges.
|
||||
if natRange.MinAddr != natRange.MaxAddr {
|
||||
nflog("dnatTargetMakerR1: MinAddr and MaxAddr are different")
|
||||
return nil, syserr.ErrInvalidArgument
|
||||
}
|
||||
if natRange.MinProto != natRange.MaxProto {
|
||||
nflog("dnatTargetMakerR1: MinProto and MaxProto are different")
|
||||
return nil, syserr.ErrInvalidArgument
|
||||
}
|
||||
|
||||
// TODO(gvisor.dev/issue/5698): Support other NF_NAT_RANGE flags.
|
||||
if natRange.Flags != linux.NF_NAT_RANGE_MAP_IPS|linux.NF_NAT_RANGE_PROTO_SPECIFIED {
|
||||
nflog("dnatTargetMakerR1: invalid range flags %d", natRange.Flags)
|
||||
return nil, syserr.ErrInvalidArgument
|
||||
}
|
||||
|
||||
target := dnatTarget{
|
||||
DNATTarget: stack.DNATTarget{
|
||||
NetworkProtocol: filter.NetworkProtocol(),
|
||||
Port: ntohs(natRange.MinProto),
|
||||
},
|
||||
}
|
||||
switch st.NetworkProtocol {
|
||||
case header.IPv4ProtocolNumber:
|
||||
target.DNATTarget.Addr = tcpip.AddrFrom4Slice(natRange.MinAddr[:4])
|
||||
case header.IPv6ProtocolNumber:
|
||||
target.DNATTarget.Addr = tcpip.AddrFrom16(natRange.MinAddr)
|
||||
default:
|
||||
panic(fmt.Sprintf("invalid protocol number: %d", st.NetworkProtocol))
|
||||
}
|
||||
|
||||
return &target, nil
|
||||
}
|
||||
|
||||
@@ -83,6 +83,12 @@ func init() {
|
||||
registerTargetMaker(&dnatTargetMakerV4{
|
||||
NetworkProtocol: header.IPv4ProtocolNumber,
|
||||
})
|
||||
registerTargetMaker(&dnatTargetMakerR1{
|
||||
NetworkProtocol: header.IPv4ProtocolNumber,
|
||||
})
|
||||
registerTargetMaker(&dnatTargetMakerR1{
|
||||
NetworkProtocol: header.IPv6ProtocolNumber,
|
||||
})
|
||||
}
|
||||
|
||||
// The stack package provides some basic, useful targets for us. The following
|
||||
|
||||
Reference in New Issue
Block a user