Explicitly allow martian loopback packets

...instead of opting out of them.

Loopback traffic should be stack-local but gVisor has some clients
that depend on the ability to receive loopback traffic that originated
from outside of the stack. Because of this, we guard this change behind
IP protocol options.

A previous change provided the facility to deny these martian loopback
packets but this change requires client to opt-in to accepting martian
loopback packets as accepting martian loopback packets are not meant
to be accepted, as per RFC 1122 section 3.2.1.3.g:

        (g)  { 127, <any> }

             Internal host loopback address.  Addresses of this form
             MUST NOT appear outside a host.

PiperOrigin-RevId: 364581174
This commit is contained in:
Ghanan Gowripalan
2021-03-23 09:57:01 -07:00
committed by gVisor bot
parent 7dbd6924a3
commit 409a114454
4 changed files with 116 additions and 116 deletions
+4 -4
View File
@@ -641,7 +641,7 @@ func (e *endpoint) HandlePacket(pkt *stack.PacketBuffer) {
}
if !e.nic.IsLoopback() {
if e.protocol.options.DropExternalLoopbackTraffic {
if !e.protocol.options.AllowExternalLoopbackTraffic {
if header.IsV4LoopbackAddress(h.SourceAddress()) {
stats.InvalidSourceAddressesReceived.Increment()
return
@@ -1230,9 +1230,9 @@ type Options struct {
// IGMP holds options for IGMP.
IGMP IGMPOptions
// DropExternalLoopbackTraffic indicates that inbound loopback packets (i.e.
// martian loopback packets) should be dropped.
DropExternalLoopbackTraffic bool
// AllowExternalLoopbackTraffic indicates that inbound loopback packets (i.e.
// martian loopback packets) should be accepted.
AllowExternalLoopbackTraffic bool
}
// NewProtocolWithOptions returns an IPv4 network protocol.
+4 -4
View File
@@ -931,7 +931,7 @@ func (e *endpoint) HandlePacket(pkt *stack.PacketBuffer) {
}
if !e.nic.IsLoopback() {
if e.protocol.options.DropExternalLoopbackTraffic {
if !e.protocol.options.AllowExternalLoopbackTraffic {
if header.IsV6LoopbackAddress(h.SourceAddress()) {
stats.InvalidSourceAddressesReceived.Increment()
return
@@ -2071,9 +2071,9 @@ type Options struct {
// DADConfigs holds the default DAD configurations used by IPv6 endpoints.
DADConfigs stack.DADConfigurations
// DropExternalLoopbackTraffic indicates that inbound loopback packets (i.e.
// martian loopback packets) should be dropped.
DropExternalLoopbackTraffic bool
// AllowExternalLoopbackTraffic indicates that inbound loopback packets (i.e.
// martian loopback packets) should be accepted.
AllowExternalLoopbackTraffic bool
}
// NewProtocolWithOptions returns an IPv6 network protocol.
+104 -104
View File
@@ -540,141 +540,141 @@ func TestExternalLoopbackTraffic(t *testing.T) {
}
tests := []struct {
name string
dropExternalLoopback bool
forwarding bool
rxICMP func(*channel.Endpoint)
invalidAddressStat func(tcpip.IPStats) *tcpip.StatCounter
shouldAccept bool
name string
allowExternalLoopback bool
forwarding bool
rxICMP func(*channel.Endpoint)
invalidAddressStat func(tcpip.IPStats) *tcpip.StatCounter
shouldAccept bool
}{
{
name: "IPv4 external loopback sourced traffic without forwarding and drop external loopback disabled",
dropExternalLoopback: false,
forwarding: false,
rxICMP: loopbackSourcedICMPv4,
invalidAddressStat: invalidSrcAddrStat,
shouldAccept: true,
name: "IPv4 external loopback sourced traffic without forwarding and drop external loopback disabled",
allowExternalLoopback: true,
forwarding: false,
rxICMP: loopbackSourcedICMPv4,
invalidAddressStat: invalidSrcAddrStat,
shouldAccept: true,
},
{
name: "IPv4 external loopback sourced traffic without forwarding and drop external loopback enabled",
dropExternalLoopback: true,
forwarding: false,
rxICMP: loopbackSourcedICMPv4,
invalidAddressStat: invalidSrcAddrStat,
shouldAccept: false,
name: "IPv4 external loopback sourced traffic without forwarding and drop external loopback enabled",
allowExternalLoopback: false,
forwarding: false,
rxICMP: loopbackSourcedICMPv4,
invalidAddressStat: invalidSrcAddrStat,
shouldAccept: false,
},
{
name: "IPv4 external loopback sourced traffic with forwarding and drop external loopback disabled",
dropExternalLoopback: false,
forwarding: true,
rxICMP: loopbackSourcedICMPv4,
invalidAddressStat: invalidSrcAddrStat,
shouldAccept: true,
name: "IPv4 external loopback sourced traffic with forwarding and drop external loopback disabled",
allowExternalLoopback: true,
forwarding: true,
rxICMP: loopbackSourcedICMPv4,
invalidAddressStat: invalidSrcAddrStat,
shouldAccept: true,
},
{
name: "IPv4 external loopback sourced traffic with forwarding and drop external loopback enabled",
dropExternalLoopback: true,
forwarding: true,
rxICMP: loopbackSourcedICMPv4,
invalidAddressStat: invalidSrcAddrStat,
shouldAccept: false,
name: "IPv4 external loopback sourced traffic with forwarding and drop external loopback enabled",
allowExternalLoopback: false,
forwarding: true,
rxICMP: loopbackSourcedICMPv4,
invalidAddressStat: invalidSrcAddrStat,
shouldAccept: false,
},
{
name: "IPv4 external loopback destined traffic without forwarding and drop external loopback disabled",
dropExternalLoopback: false,
forwarding: false,
rxICMP: loopbackDestinedICMPv4,
invalidAddressStat: invalidDestAddrStat,
shouldAccept: false,
name: "IPv4 external loopback destined traffic without forwarding and drop external loopback disabled",
allowExternalLoopback: true,
forwarding: false,
rxICMP: loopbackDestinedICMPv4,
invalidAddressStat: invalidDestAddrStat,
shouldAccept: false,
},
{
name: "IPv4 external loopback destined traffic without forwarding and drop external loopback enabled",
dropExternalLoopback: true,
forwarding: false,
rxICMP: loopbackDestinedICMPv4,
invalidAddressStat: invalidDestAddrStat,
shouldAccept: false,
name: "IPv4 external loopback destined traffic without forwarding and drop external loopback enabled",
allowExternalLoopback: false,
forwarding: false,
rxICMP: loopbackDestinedICMPv4,
invalidAddressStat: invalidDestAddrStat,
shouldAccept: false,
},
{
name: "IPv4 external loopback destined traffic with forwarding and drop external loopback disabled",
dropExternalLoopback: false,
forwarding: true,
rxICMP: loopbackDestinedICMPv4,
invalidAddressStat: invalidDestAddrStat,
shouldAccept: true,
name: "IPv4 external loopback destined traffic with forwarding and drop external loopback disabled",
allowExternalLoopback: true,
forwarding: true,
rxICMP: loopbackDestinedICMPv4,
invalidAddressStat: invalidDestAddrStat,
shouldAccept: true,
},
{
name: "IPv4 external loopback destined traffic with forwarding and drop external loopback enabled",
dropExternalLoopback: true,
forwarding: true,
rxICMP: loopbackDestinedICMPv4,
invalidAddressStat: invalidDestAddrStat,
shouldAccept: false,
name: "IPv4 external loopback destined traffic with forwarding and drop external loopback enabled",
allowExternalLoopback: false,
forwarding: true,
rxICMP: loopbackDestinedICMPv4,
invalidAddressStat: invalidDestAddrStat,
shouldAccept: false,
},
{
name: "IPv6 external loopback sourced traffic without forwarding and drop external loopback disabled",
dropExternalLoopback: false,
forwarding: false,
rxICMP: loopbackSourcedICMPv6,
invalidAddressStat: invalidSrcAddrStat,
shouldAccept: true,
name: "IPv6 external loopback sourced traffic without forwarding and drop external loopback disabled",
allowExternalLoopback: true,
forwarding: false,
rxICMP: loopbackSourcedICMPv6,
invalidAddressStat: invalidSrcAddrStat,
shouldAccept: true,
},
{
name: "IPv6 external loopback sourced traffic without forwarding and drop external loopback enabled",
dropExternalLoopback: true,
forwarding: false,
rxICMP: loopbackSourcedICMPv6,
invalidAddressStat: invalidSrcAddrStat,
shouldAccept: false,
name: "IPv6 external loopback sourced traffic without forwarding and drop external loopback enabled",
allowExternalLoopback: false,
forwarding: false,
rxICMP: loopbackSourcedICMPv6,
invalidAddressStat: invalidSrcAddrStat,
shouldAccept: false,
},
{
name: "IPv6 external loopback sourced traffic with forwarding and drop external loopback disabled",
dropExternalLoopback: false,
forwarding: true,
rxICMP: loopbackSourcedICMPv6,
invalidAddressStat: invalidSrcAddrStat,
shouldAccept: true,
name: "IPv6 external loopback sourced traffic with forwarding and drop external loopback disabled",
allowExternalLoopback: true,
forwarding: true,
rxICMP: loopbackSourcedICMPv6,
invalidAddressStat: invalidSrcAddrStat,
shouldAccept: true,
},
{
name: "IPv6 external loopback sourced traffic with forwarding and drop external loopback enabled",
dropExternalLoopback: true,
forwarding: true,
rxICMP: loopbackSourcedICMPv6,
invalidAddressStat: invalidSrcAddrStat,
shouldAccept: false,
name: "IPv6 external loopback sourced traffic with forwarding and drop external loopback enabled",
allowExternalLoopback: false,
forwarding: true,
rxICMP: loopbackSourcedICMPv6,
invalidAddressStat: invalidSrcAddrStat,
shouldAccept: false,
},
{
name: "IPv6 external loopback destined traffic without forwarding and drop external loopback disabled",
dropExternalLoopback: false,
forwarding: false,
rxICMP: loopbackDestinedICMPv6,
invalidAddressStat: invalidDestAddrStat,
shouldAccept: false,
name: "IPv6 external loopback destined traffic without forwarding and drop external loopback disabled",
allowExternalLoopback: true,
forwarding: false,
rxICMP: loopbackDestinedICMPv6,
invalidAddressStat: invalidDestAddrStat,
shouldAccept: false,
},
{
name: "IPv6 external loopback destined traffic without forwarding and drop external loopback enabled",
dropExternalLoopback: true,
forwarding: false,
rxICMP: loopbackDestinedICMPv6,
invalidAddressStat: invalidDestAddrStat,
shouldAccept: false,
name: "IPv6 external loopback destined traffic without forwarding and drop external loopback enabled",
allowExternalLoopback: false,
forwarding: false,
rxICMP: loopbackDestinedICMPv6,
invalidAddressStat: invalidDestAddrStat,
shouldAccept: false,
},
{
name: "IPv6 external loopback destined traffic with forwarding and drop external loopback disabled",
dropExternalLoopback: false,
forwarding: true,
rxICMP: loopbackDestinedICMPv6,
invalidAddressStat: invalidDestAddrStat,
shouldAccept: true,
name: "IPv6 external loopback destined traffic with forwarding and drop external loopback disabled",
allowExternalLoopback: true,
forwarding: true,
rxICMP: loopbackDestinedICMPv6,
invalidAddressStat: invalidDestAddrStat,
shouldAccept: true,
},
{
name: "IPv6 external loopback destined traffic with forwarding and drop external loopback enabled",
dropExternalLoopback: true,
forwarding: true,
rxICMP: loopbackDestinedICMPv6,
invalidAddressStat: invalidDestAddrStat,
shouldAccept: false,
name: "IPv6 external loopback destined traffic with forwarding and drop external loopback enabled",
allowExternalLoopback: false,
forwarding: true,
rxICMP: loopbackDestinedICMPv6,
invalidAddressStat: invalidDestAddrStat,
shouldAccept: false,
},
}
@@ -683,10 +683,10 @@ func TestExternalLoopbackTraffic(t *testing.T) {
s := stack.New(stack.Options{
NetworkProtocols: []stack.NetworkProtocolFactory{
ipv4.NewProtocolWithOptions(ipv4.Options{
DropExternalLoopbackTraffic: test.dropExternalLoopback,
AllowExternalLoopbackTraffic: test.allowExternalLoopback,
}),
ipv6.NewProtocolWithOptions(ipv6.Options{
DropExternalLoopbackTraffic: test.dropExternalLoopback,
AllowExternalLoopbackTraffic: test.allowExternalLoopback,
}),
},
TransportProtocols: []stack.TransportProtocolFactory{icmp.NewProtocol4, icmp.NewProtocol6},
+4 -4
View File
@@ -162,15 +162,15 @@ func TestLocalPing(t *testing.T) {
for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
for _, dropExternalLoopback := range []bool{true, false} {
t.Run(fmt.Sprintf("DropExternalLoopback=%t", dropExternalLoopback), func(t *testing.T) {
for _, allowExternalLoopback := range []bool{true, false} {
t.Run(fmt.Sprintf("AllowExternalLoopback=%t", allowExternalLoopback), func(t *testing.T) {
s := stack.New(stack.Options{
NetworkProtocols: []stack.NetworkProtocolFactory{
ipv4.NewProtocolWithOptions(ipv4.Options{
DropExternalLoopbackTraffic: dropExternalLoopback,
AllowExternalLoopbackTraffic: allowExternalLoopback,
}),
ipv6.NewProtocolWithOptions(ipv6.Options{
DropExternalLoopbackTraffic: dropExternalLoopback,
AllowExternalLoopbackTraffic: allowExternalLoopback,
}),
},
TransportProtocols: []stack.TransportProtocolFactory{icmp.NewProtocol4, icmp.NewProtocol6},