Don't support address ranges

Previously the netstack supported assignment of a range of addresses.
This feature is not used so remove it.

PiperOrigin-RevId: 326791119
This commit is contained in:
Ghanan Gowripalan 2020-08-15 00:04:30 -07:00 committed by gVisor bot
parent 1736b2208f
commit 9a7b5830aa
3 changed files with 8 additions and 278 deletions

View File

@ -51,13 +51,12 @@ type NIC struct {
mu struct { mu struct {
sync.RWMutex sync.RWMutex
enabled bool enabled bool
spoofing bool spoofing bool
promiscuous bool promiscuous bool
primary map[tcpip.NetworkProtocolNumber][]*referencedNetworkEndpoint primary map[tcpip.NetworkProtocolNumber][]*referencedNetworkEndpoint
endpoints map[NetworkEndpointID]*referencedNetworkEndpoint endpoints map[NetworkEndpointID]*referencedNetworkEndpoint
addressRanges []tcpip.Subnet mcastJoins map[NetworkEndpointID]uint32
mcastJoins map[NetworkEndpointID]uint32
// packetEPs is protected by mu, but the contained PacketEndpoint // packetEPs is protected by mu, but the contained PacketEndpoint
// values are not. // values are not.
packetEPs map[tcpip.NetworkProtocolNumber][]PacketEndpoint packetEPs map[tcpip.NetworkProtocolNumber][]PacketEndpoint
@ -670,25 +669,6 @@ func (n *NIC) getRefOrCreateTemp(protocol tcpip.NetworkProtocolNumber, address t
// A usable reference was not found, create a temporary one if requested by // A usable reference was not found, create a temporary one if requested by
// the caller or if the address is found in the NIC's subnets. // the caller or if the address is found in the NIC's subnets.
createTempEP := spoofingOrPromiscuous createTempEP := spoofingOrPromiscuous
if !createTempEP {
for _, sn := range n.mu.addressRanges {
// Skip the subnet address.
if address == sn.ID() {
continue
}
// For now just skip the broadcast address, until we support it.
// FIXME(b/137608825): Add support for sending/receiving directed
// (subnet) broadcast.
if address == sn.Broadcast() {
continue
}
if sn.Contains(address) {
createTempEP = true
break
}
}
}
n.mu.RUnlock() n.mu.RUnlock()
if !createTempEP { if !createTempEP {
@ -982,38 +962,11 @@ func (n *NIC) primaryAddress(proto tcpip.NetworkProtocolNumber) tcpip.AddressWit
return tcpip.AddressWithPrefix{} return tcpip.AddressWithPrefix{}
} }
// AddAddressRange adds a range of addresses to n, so that it starts accepting
// packets targeted at the given addresses and network protocol. The range is
// given by a subnet address, and all addresses contained in the subnet are
// used except for the subnet address itself and the subnet's broadcast
// address.
func (n *NIC) AddAddressRange(protocol tcpip.NetworkProtocolNumber, subnet tcpip.Subnet) {
n.mu.Lock()
n.mu.addressRanges = append(n.mu.addressRanges, subnet)
n.mu.Unlock()
}
// RemoveAddressRange removes the given address range from n.
func (n *NIC) RemoveAddressRange(subnet tcpip.Subnet) {
n.mu.Lock()
// Use the same underlying array.
tmp := n.mu.addressRanges[:0]
for _, sub := range n.mu.addressRanges {
if sub != subnet {
tmp = append(tmp, sub)
}
}
n.mu.addressRanges = tmp
n.mu.Unlock()
}
// AddressRanges returns the Subnets associated with this NIC. // AddressRanges returns the Subnets associated with this NIC.
func (n *NIC) AddressRanges() []tcpip.Subnet { func (n *NIC) AddressRanges() []tcpip.Subnet {
n.mu.RLock() n.mu.RLock()
defer n.mu.RUnlock() defer n.mu.RUnlock()
sns := make([]tcpip.Subnet, 0, len(n.mu.addressRanges)+len(n.mu.endpoints)) sns := make([]tcpip.Subnet, 0, len(n.mu.endpoints))
for nid := range n.mu.endpoints { for nid := range n.mu.endpoints {
sn, err := tcpip.NewSubnet(nid.LocalAddress, tcpip.AddressMask(strings.Repeat("\xff", len(nid.LocalAddress)))) sn, err := tcpip.NewSubnet(nid.LocalAddress, tcpip.AddressMask(strings.Repeat("\xff", len(nid.LocalAddress))))
if err != nil { if err != nil {
@ -1023,7 +976,7 @@ func (n *NIC) AddressRanges() []tcpip.Subnet {
} }
sns = append(sns, sn) sns = append(sns, sn)
} }
return append(sns, n.mu.addressRanges...) return sns
} }
// insertPrimaryEndpointLocked adds r to n's primary endpoint list as required // insertPrimaryEndpointLocked adds r to n's primary endpoint list as required

View File

@ -1230,35 +1230,6 @@ func (s *Stack) AddProtocolAddressWithOptions(id tcpip.NICID, protocolAddress tc
return nic.AddAddress(protocolAddress, peb) return nic.AddAddress(protocolAddress, peb)
} }
// AddAddressRange adds a range of addresses to the specified NIC. The range is
// given by a subnet address, and all addresses contained in the subnet are
// used except for the subnet address itself and the subnet's broadcast
// address.
func (s *Stack) AddAddressRange(id tcpip.NICID, protocol tcpip.NetworkProtocolNumber, subnet tcpip.Subnet) *tcpip.Error {
s.mu.RLock()
defer s.mu.RUnlock()
if nic, ok := s.nics[id]; ok {
nic.AddAddressRange(protocol, subnet)
return nil
}
return tcpip.ErrUnknownNICID
}
// RemoveAddressRange removes the range of addresses from the specified NIC.
func (s *Stack) RemoveAddressRange(id tcpip.NICID, subnet tcpip.Subnet) *tcpip.Error {
s.mu.RLock()
defer s.mu.RUnlock()
if nic, ok := s.nics[id]; ok {
nic.RemoveAddressRange(subnet)
return nil
}
return tcpip.ErrUnknownNICID
}
// RemoveAddress removes an existing network-layer address from the specified // RemoveAddress removes an existing network-layer address from the specified
// NIC. // NIC.
func (s *Stack) RemoveAddress(id tcpip.NICID, addr tcpip.Address) *tcpip.Error { func (s *Stack) RemoveAddress(id tcpip.NICID, addr tcpip.Address) *tcpip.Error {

View File

@ -23,7 +23,6 @@ import (
"math" "math"
"net" "net"
"sort" "sort"
"strings"
"testing" "testing"
"time" "time"
@ -1641,149 +1640,6 @@ func TestMulticastOrIPv6LinkLocalNeedsNoRoute(t *testing.T) {
} }
} }
// Add a range of addresses, then check that a packet is delivered.
func TestAddressRangeAcceptsMatchingPacket(t *testing.T) {
s := stack.New(stack.Options{
NetworkProtocols: []stack.NetworkProtocol{fakeNetFactory()},
})
ep := channel.New(10, defaultMTU, "")
if err := s.CreateNIC(1, ep); err != nil {
t.Fatal("CreateNIC failed:", err)
}
{
subnet, err := tcpip.NewSubnet("\x00", "\x00")
if err != nil {
t.Fatal(err)
}
s.SetRouteTable([]tcpip.Route{{Destination: subnet, Gateway: "\x00", NIC: 1}})
}
fakeNet := s.NetworkProtocolInstance(fakeNetNumber).(*fakeNetworkProtocol)
buf := buffer.NewView(30)
const localAddrByte byte = 0x01
buf[dstAddrOffset] = localAddrByte
subnet, err := tcpip.NewSubnet(tcpip.Address("\x00"), tcpip.AddressMask("\xF0"))
if err != nil {
t.Fatal("NewSubnet failed:", err)
}
if err := s.AddAddressRange(1, fakeNetNumber, subnet); err != nil {
t.Fatal("AddAddressRange failed:", err)
}
testRecv(t, fakeNet, localAddrByte, ep, buf)
}
func testNicForAddressRange(t *testing.T, nicID tcpip.NICID, s *stack.Stack, subnet tcpip.Subnet, rangeExists bool) {
t.Helper()
// Loop over all addresses and check them.
numOfAddresses := 1 << uint(8-subnet.Prefix())
if numOfAddresses < 1 || numOfAddresses > 255 {
t.Fatalf("got numOfAddresses = %d, want = [1 .. 255] (subnet=%s)", numOfAddresses, subnet)
}
addrBytes := []byte(subnet.ID())
for i := 0; i < numOfAddresses; i++ {
addr := tcpip.Address(addrBytes)
wantNicID := nicID
// The subnet and broadcast addresses are skipped.
if !rangeExists || addr == subnet.ID() || addr == subnet.Broadcast() {
wantNicID = 0
}
if gotNicID := s.CheckLocalAddress(0, fakeNetNumber, addr); gotNicID != wantNicID {
t.Errorf("got CheckLocalAddress(0, %d, %s) = %d, want = %d", fakeNetNumber, addr, gotNicID, wantNicID)
}
addrBytes[0]++
}
// Trying the next address should always fail since it is outside the range.
if gotNicID := s.CheckLocalAddress(0, fakeNetNumber, tcpip.Address(addrBytes)); gotNicID != 0 {
t.Errorf("got CheckLocalAddress(0, %d, %s) = %d, want = 0", fakeNetNumber, tcpip.Address(addrBytes), gotNicID)
}
}
// Set a range of addresses, then remove it again, and check at each step that
// CheckLocalAddress returns the correct NIC for each address or zero if not
// existent.
func TestCheckLocalAddressForSubnet(t *testing.T) {
const nicID tcpip.NICID = 1
s := stack.New(stack.Options{
NetworkProtocols: []stack.NetworkProtocol{fakeNetFactory()},
})
ep := channel.New(10, defaultMTU, "")
if err := s.CreateNIC(nicID, ep); err != nil {
t.Fatal("CreateNIC failed:", err)
}
{
subnet, err := tcpip.NewSubnet("\x00", "\x00")
if err != nil {
t.Fatal(err)
}
s.SetRouteTable([]tcpip.Route{{Destination: subnet, Gateway: "\x00", NIC: nicID}})
}
subnet, err := tcpip.NewSubnet(tcpip.Address("\xa0"), tcpip.AddressMask("\xf0"))
if err != nil {
t.Fatal("NewSubnet failed:", err)
}
testNicForAddressRange(t, nicID, s, subnet, false /* rangeExists */)
if err := s.AddAddressRange(nicID, fakeNetNumber, subnet); err != nil {
t.Fatal("AddAddressRange failed:", err)
}
testNicForAddressRange(t, nicID, s, subnet, true /* rangeExists */)
if err := s.RemoveAddressRange(nicID, subnet); err != nil {
t.Fatal("RemoveAddressRange failed:", err)
}
testNicForAddressRange(t, nicID, s, subnet, false /* rangeExists */)
}
// Set a range of addresses, then send a packet to a destination outside the
// range and then check it doesn't get delivered.
func TestAddressRangeRejectsNonmatchingPacket(t *testing.T) {
s := stack.New(stack.Options{
NetworkProtocols: []stack.NetworkProtocol{fakeNetFactory()},
})
ep := channel.New(10, defaultMTU, "")
if err := s.CreateNIC(1, ep); err != nil {
t.Fatal("CreateNIC failed:", err)
}
{
subnet, err := tcpip.NewSubnet("\x00", "\x00")
if err != nil {
t.Fatal(err)
}
s.SetRouteTable([]tcpip.Route{{Destination: subnet, Gateway: "\x00", NIC: 1}})
}
fakeNet := s.NetworkProtocolInstance(fakeNetNumber).(*fakeNetworkProtocol)
buf := buffer.NewView(30)
const localAddrByte byte = 0x01
buf[dstAddrOffset] = localAddrByte
subnet, err := tcpip.NewSubnet(tcpip.Address("\x10"), tcpip.AddressMask("\xF0"))
if err != nil {
t.Fatal("NewSubnet failed:", err)
}
if err := s.AddAddressRange(1, fakeNetNumber, subnet); err != nil {
t.Fatal("AddAddressRange failed:", err)
}
testFailingRecv(t, fakeNet, localAddrByte, ep, buf)
}
func TestNetworkOptions(t *testing.T) { func TestNetworkOptions(t *testing.T) {
s := stack.New(stack.Options{ s := stack.New(stack.Options{
NetworkProtocols: []stack.NetworkProtocol{fakeNetFactory()}, NetworkProtocols: []stack.NetworkProtocol{fakeNetFactory()},
@ -1827,56 +1683,6 @@ func TestNetworkOptions(t *testing.T) {
} }
} }
func stackContainsAddressRange(s *stack.Stack, id tcpip.NICID, addrRange tcpip.Subnet) bool {
ranges, ok := s.NICAddressRanges()[id]
if !ok {
return false
}
for _, r := range ranges {
if r == addrRange {
return true
}
}
return false
}
func TestAddresRangeAddRemove(t *testing.T) {
s := stack.New(stack.Options{
NetworkProtocols: []stack.NetworkProtocol{fakeNetFactory()},
})
ep := channel.New(10, defaultMTU, "")
if err := s.CreateNIC(1, ep); err != nil {
t.Fatal("CreateNIC failed:", err)
}
addr := tcpip.Address("\x01\x01\x01\x01")
mask := tcpip.AddressMask(strings.Repeat("\xff", len(addr)))
addrRange, err := tcpip.NewSubnet(addr, mask)
if err != nil {
t.Fatal("NewSubnet failed:", err)
}
if got, want := stackContainsAddressRange(s, 1, addrRange), false; got != want {
t.Fatalf("got stackContainsAddressRange(...) = %t, want = %t", got, want)
}
if err := s.AddAddressRange(1, fakeNetNumber, addrRange); err != nil {
t.Fatal("AddAddressRange failed:", err)
}
if got, want := stackContainsAddressRange(s, 1, addrRange), true; got != want {
t.Fatalf("got stackContainsAddressRange(...) = %t, want = %t", got, want)
}
if err := s.RemoveAddressRange(1, addrRange); err != nil {
t.Fatal("RemoveAddressRange failed:", err)
}
if got, want := stackContainsAddressRange(s, 1, addrRange), false; got != want {
t.Fatalf("got stackContainsAddressRange(...) = %t, want = %t", got, want)
}
}
func TestGetMainNICAddressAddPrimaryNonPrimary(t *testing.T) { func TestGetMainNICAddressAddPrimaryNonPrimary(t *testing.T) {
for _, addrLen := range []int{4, 16} { for _, addrLen := range []int{4, 16} {
t.Run(fmt.Sprintf("addrLen=%d", addrLen), func(t *testing.T) { t.Run(fmt.Sprintf("addrLen=%d", addrLen), func(t *testing.T) {