summaryrefslogtreecommitdiffhomepage
path: root/pkg/tcpip
diff options
context:
space:
mode:
authorNayana Bidari <nybidari@google.com>2020-02-28 10:00:38 -0800
committerNayana Bidari <nybidari@google.com>2020-02-28 10:00:38 -0800
commitaf6fab651406c411ef848c360b017713de385880 (patch)
tree155e1ccf89f04a01226448be13df3dd47c060137 /pkg/tcpip
parent9fccf98c0d990cb32666091855f3a396f762ce55 (diff)
Add nat table support for iptables.
- Fix review comments.
Diffstat (limited to 'pkg/tcpip')
-rw-r--r--pkg/tcpip/iptables/targets.go55
-rw-r--r--pkg/tcpip/iptables/types.go2
2 files changed, 43 insertions, 14 deletions
diff --git a/pkg/tcpip/iptables/targets.go b/pkg/tcpip/iptables/targets.go
index 96318118c..ae5af7c53 100644
--- a/pkg/tcpip/iptables/targets.go
+++ b/pkg/tcpip/iptables/targets.go
@@ -69,8 +69,11 @@ func (ReturnTarget) Action(tcpip.PacketBuffer) (RuleVerdict, int) {
// Min and Max values for IP and Ports in the struct indicate the range of
// values which can be used to redirect.
type RedirectTarget struct {
- // Flags to check if the redirect is for address or ports.
- Flags uint32
+ // TODO(gvisor.dev/issue/170): Other flags need to be aded after
+ // we support them.
+ // RangeProtoSpecified flag indicates single port is specified to
+ // redirect.
+ RangeProtoSpecified bool
// Min address used to redirect.
MinIP tcpip.Address
@@ -86,30 +89,56 @@ type RedirectTarget struct {
}
// Action implements Target.Action.
+// TODO(gvisor.dev/issue/170): Parse headers without copying. The current
+// implementation only works for PREROUTING and calls pkt.Clone(), neither
+// of which should be the case.
func (rt RedirectTarget) Action(pkt tcpip.PacketBuffer) (RuleVerdict, int) {
- headerView := pkt.Data.First()
+ newPkt := pkt.Clone()
- // Network header should be set.
+ // Set network header.
+ headerView := newPkt.Data.First()
netHeader := header.IPv4(headerView)
- if netHeader == nil {
- return RuleDrop, 0
- }
+ newPkt.NetworkHeader = headerView[:netHeader.HeaderLength()]
- // TODO(gvisor.dev/issue/170): Check Flags in RedirectTarget if
- // we need to change dest address (for OUTPUT chain) or ports.
hlen := int(netHeader.HeaderLength())
+ tlen := int(netHeader.TotalLength())
+ newPkt.Data.TrimFront(hlen)
+ newPkt.Data.CapLength(tlen - hlen)
+ // TODO(gvisor.dev/issue/170): Change destination address to
+ // loopback or interface address on which the packet was
+ // received.
+
+ // TODO(gvisor.dev/issue/170): Check Flags in RedirectTarget if
+ // we need to change dest address (for OUTPUT chain) or ports.
switch protocol := netHeader.TransportProtocol(); protocol {
case header.UDPProtocolNumber:
- udp := header.UDP(headerView[hlen:])
- udp.SetDestinationPort(rt.MinPort)
+ var udpHeader header.UDP
+ if newPkt.TransportHeader != nil {
+ udpHeader = header.UDP(newPkt.TransportHeader)
+ } else {
+ if len(pkt.Data.First()) < header.UDPMinimumSize {
+ return RuleDrop, 0
+ }
+ udpHeader = header.UDP(newPkt.Data.First())
+ }
+ udpHeader.SetDestinationPort(rt.MinPort)
case header.TCPProtocolNumber:
+ var tcpHeader header.TCP
+ if newPkt.TransportHeader != nil {
+ tcpHeader = header.TCP(newPkt.TransportHeader)
+ } else {
+ if len(pkt.Data.First()) < header.TCPMinimumSize {
+ return RuleDrop, 0
+ }
+ tcpHeader = header.TCP(newPkt.TransportHeader)
+ }
// TODO(gvisor.dev/issue/170): Need to recompute checksum
// and implement nat connection tracking to support TCP.
- tcp := header.TCP(headerView[hlen:])
- tcp.SetDestinationPort(rt.MinPort)
+ tcpHeader.SetDestinationPort(rt.MinPort)
default:
return RuleDrop, 0
}
+
return RuleAccept, 0
}
diff --git a/pkg/tcpip/iptables/types.go b/pkg/tcpip/iptables/types.go
index 9c2ad2d46..7d032fd23 100644
--- a/pkg/tcpip/iptables/types.go
+++ b/pkg/tcpip/iptables/types.go
@@ -163,6 +163,6 @@ type Matcher interface {
type Target interface {
// Action takes an action on the packet and returns a verdict on how
// traversal should (or should not) continue. If the return value is
- // Jump, it also returns the name of the chain to jump to.
+ // Jump, it also returns the index of the rule to jump to.
Action(packet tcpip.PacketBuffer) (RuleVerdict, int)
}