diff options
-rwxr-xr-x | pkg/sentry/kernel/seqatomic_taskgoroutineschedinfo_unsafe.go | 3 | ||||
-rwxr-xr-x | pkg/sentry/platform/ring0/defs_impl.go | 8 | ||||
-rw-r--r-- | pkg/sentry/socket/epsocket/stack.go | 4 | ||||
-rwxr-xr-x | pkg/sentry/time/seqatomic_parameters_unsafe.go | 3 | ||||
-rw-r--r-- | pkg/tcpip/network/arp/arp.go | 11 | ||||
-rw-r--r-- | pkg/tcpip/network/ipv4/ipv4.go | 16 | ||||
-rw-r--r-- | pkg/tcpip/network/ipv6/ipv6.go | 16 | ||||
-rw-r--r-- | pkg/tcpip/stack/nic.go | 66 | ||||
-rw-r--r-- | pkg/tcpip/stack/registration.go | 8 | ||||
-rw-r--r-- | pkg/tcpip/stack/stack.go | 23 | ||||
-rw-r--r-- | pkg/tcpip/tcpip.go | 13 |
11 files changed, 117 insertions, 54 deletions
diff --git a/pkg/sentry/kernel/seqatomic_taskgoroutineschedinfo_unsafe.go b/pkg/sentry/kernel/seqatomic_taskgoroutineschedinfo_unsafe.go index 25ad17a4e..be6b07629 100755 --- a/pkg/sentry/kernel/seqatomic_taskgoroutineschedinfo_unsafe.go +++ b/pkg/sentry/kernel/seqatomic_taskgoroutineschedinfo_unsafe.go @@ -2,11 +2,10 @@ package kernel import ( "fmt" + "gvisor.dev/gvisor/third_party/gvsync" "reflect" "strings" "unsafe" - - "gvisor.dev/gvisor/third_party/gvsync" ) // SeqAtomicLoad returns a copy of *ptr, ensuring that the read does not race diff --git a/pkg/sentry/platform/ring0/defs_impl.go b/pkg/sentry/platform/ring0/defs_impl.go index d4bfc5a4a..acae012dc 100755 --- a/pkg/sentry/platform/ring0/defs_impl.go +++ b/pkg/sentry/platform/ring0/defs_impl.go @@ -1,14 +1,14 @@ package ring0 import ( - "syscall" - "fmt" "gvisor.dev/gvisor/pkg/cpuid" - "gvisor.dev/gvisor/pkg/sentry/platform/ring0/pagetables" - "gvisor.dev/gvisor/pkg/sentry/usermem" "io" "reflect" + "syscall" + + "gvisor.dev/gvisor/pkg/sentry/platform/ring0/pagetables" + "gvisor.dev/gvisor/pkg/sentry/usermem" ) var ( diff --git a/pkg/sentry/socket/epsocket/stack.go b/pkg/sentry/socket/epsocket/stack.go index 7eef19f74..8fe489c0e 100644 --- a/pkg/sentry/socket/epsocket/stack.go +++ b/pkg/sentry/socket/epsocket/stack.go @@ -75,8 +75,8 @@ func (s *Stack) InterfaceAddrs() map[int32][]inet.InterfaceAddr { addrs = append(addrs, inet.InterfaceAddr{ Family: family, - PrefixLen: uint8(len(a.Address) * 8), - Addr: []byte(a.Address), + PrefixLen: uint8(a.AddressWithPrefix.PrefixLen), + Addr: []byte(a.AddressWithPrefix.Address), // TODO(b/68878065): Other fields. }) } diff --git a/pkg/sentry/time/seqatomic_parameters_unsafe.go b/pkg/sentry/time/seqatomic_parameters_unsafe.go index 89792c56d..b4fb0a7f0 100755 --- a/pkg/sentry/time/seqatomic_parameters_unsafe.go +++ b/pkg/sentry/time/seqatomic_parameters_unsafe.go @@ -2,11 +2,10 @@ package time import ( "fmt" + "gvisor.dev/gvisor/third_party/gvsync" "reflect" "strings" "unsafe" - - "gvisor.dev/gvisor/third_party/gvsync" ) // SeqAtomicLoad returns a copy of *ptr, ensuring that the read does not race diff --git a/pkg/tcpip/network/arp/arp.go b/pkg/tcpip/network/arp/arp.go index cb35635fc..60070874d 100644 --- a/pkg/tcpip/network/arp/arp.go +++ b/pkg/tcpip/network/arp/arp.go @@ -46,7 +46,6 @@ const ( // endpoint implements stack.NetworkEndpoint. type endpoint struct { nicid tcpip.NICID - addr tcpip.Address linkEP stack.LinkEndpoint linkAddrCache stack.LinkAddressCache } @@ -73,6 +72,10 @@ func (e *endpoint) ID() *stack.NetworkEndpointID { return &stack.NetworkEndpointID{ProtocolAddress} } +func (e *endpoint) PrefixLen() int { + return 0 +} + func (e *endpoint) MaxHeaderLength() uint16 { return e.linkEP.MaxHeaderLength() + header.ARPSize } @@ -122,19 +125,19 @@ type protocol struct { func (p *protocol) Number() tcpip.NetworkProtocolNumber { return ProtocolNumber } func (p *protocol) MinimumPacketSize() int { return header.ARPSize } +func (p *protocol) DefaultPrefixLen() int { return 0 } func (*protocol) ParseAddresses(v buffer.View) (src, dst tcpip.Address) { h := header.ARP(v) return tcpip.Address(h.ProtocolAddressSender()), ProtocolAddress } -func (p *protocol) NewEndpoint(nicid tcpip.NICID, addr tcpip.Address, linkAddrCache stack.LinkAddressCache, dispatcher stack.TransportDispatcher, sender stack.LinkEndpoint) (stack.NetworkEndpoint, *tcpip.Error) { - if addr != ProtocolAddress { +func (p *protocol) NewEndpoint(nicid tcpip.NICID, addrWithPrefix tcpip.AddressWithPrefix, linkAddrCache stack.LinkAddressCache, dispatcher stack.TransportDispatcher, sender stack.LinkEndpoint) (stack.NetworkEndpoint, *tcpip.Error) { + if addrWithPrefix.Address != ProtocolAddress { return nil, tcpip.ErrBadLocalAddress } return &endpoint{ nicid: nicid, - addr: addr, linkEP: sender, linkAddrCache: linkAddrCache, }, nil diff --git a/pkg/tcpip/network/ipv4/ipv4.go b/pkg/tcpip/network/ipv4/ipv4.go index e44a73d96..b7a06f525 100644 --- a/pkg/tcpip/network/ipv4/ipv4.go +++ b/pkg/tcpip/network/ipv4/ipv4.go @@ -49,16 +49,18 @@ const ( type endpoint struct { nicid tcpip.NICID id stack.NetworkEndpointID + prefixLen int linkEP stack.LinkEndpoint dispatcher stack.TransportDispatcher fragmentation *fragmentation.Fragmentation } // NewEndpoint creates a new ipv4 endpoint. -func (p *protocol) NewEndpoint(nicid tcpip.NICID, addr tcpip.Address, linkAddrCache stack.LinkAddressCache, dispatcher stack.TransportDispatcher, linkEP stack.LinkEndpoint) (stack.NetworkEndpoint, *tcpip.Error) { +func (p *protocol) NewEndpoint(nicid tcpip.NICID, addrWithPrefix tcpip.AddressWithPrefix, linkAddrCache stack.LinkAddressCache, dispatcher stack.TransportDispatcher, linkEP stack.LinkEndpoint) (stack.NetworkEndpoint, *tcpip.Error) { e := &endpoint{ nicid: nicid, - id: stack.NetworkEndpointID{LocalAddress: addr}, + id: stack.NetworkEndpointID{LocalAddress: addrWithPrefix.Address}, + prefixLen: addrWithPrefix.PrefixLen, linkEP: linkEP, dispatcher: dispatcher, fragmentation: fragmentation.NewFragmentation(fragmentation.HighFragThreshold, fragmentation.LowFragThreshold, fragmentation.DefaultReassembleTimeout), @@ -93,6 +95,11 @@ func (e *endpoint) ID() *stack.NetworkEndpointID { return &e.id } +// PrefixLen returns the ipv4 endpoint subnet prefix length in bits. +func (e *endpoint) PrefixLen() int { + return e.prefixLen +} + // MaxHeaderLength returns the maximum length needed by ipv4 headers (and // underlying protocols). func (e *endpoint) MaxHeaderLength() uint16 { @@ -338,6 +345,11 @@ func (p *protocol) MinimumPacketSize() int { return header.IPv4MinimumSize } +// DefaultPrefixLen returns the IPv4 default prefix length. +func (p *protocol) DefaultPrefixLen() int { + return header.IPv4AddressSize * 8 +} + // ParseAddresses implements NetworkProtocol.ParseAddresses. func (*protocol) ParseAddresses(v buffer.View) (src, dst tcpip.Address) { h := header.IPv4(v) diff --git a/pkg/tcpip/network/ipv6/ipv6.go b/pkg/tcpip/network/ipv6/ipv6.go index e3e8739fd..331a8bdaa 100644 --- a/pkg/tcpip/network/ipv6/ipv6.go +++ b/pkg/tcpip/network/ipv6/ipv6.go @@ -46,6 +46,7 @@ const ( type endpoint struct { nicid tcpip.NICID id stack.NetworkEndpointID + prefixLen int linkEP stack.LinkEndpoint linkAddrCache stack.LinkAddressCache dispatcher stack.TransportDispatcher @@ -72,6 +73,11 @@ func (e *endpoint) ID() *stack.NetworkEndpointID { return &e.id } +// PrefixLen returns the ipv6 endpoint subnet prefix length in bits. +func (e *endpoint) PrefixLen() int { + return e.prefixLen +} + // Capabilities implements stack.NetworkEndpoint.Capabilities. func (e *endpoint) Capabilities() stack.LinkEndpointCapabilities { return e.linkEP.Capabilities() @@ -172,6 +178,11 @@ func (p *protocol) MinimumPacketSize() int { return header.IPv6MinimumSize } +// DefaultPrefixLen returns the IPv6 default prefix length. +func (p *protocol) DefaultPrefixLen() int { + return header.IPv6AddressSize * 8 +} + // ParseAddresses implements NetworkProtocol.ParseAddresses. func (*protocol) ParseAddresses(v buffer.View) (src, dst tcpip.Address) { h := header.IPv6(v) @@ -179,10 +190,11 @@ func (*protocol) ParseAddresses(v buffer.View) (src, dst tcpip.Address) { } // NewEndpoint creates a new ipv6 endpoint. -func (p *protocol) NewEndpoint(nicid tcpip.NICID, addr tcpip.Address, linkAddrCache stack.LinkAddressCache, dispatcher stack.TransportDispatcher, linkEP stack.LinkEndpoint) (stack.NetworkEndpoint, *tcpip.Error) { +func (p *protocol) NewEndpoint(nicid tcpip.NICID, addrWithPrefix tcpip.AddressWithPrefix, linkAddrCache stack.LinkAddressCache, dispatcher stack.TransportDispatcher, linkEP stack.LinkEndpoint) (stack.NetworkEndpoint, *tcpip.Error) { return &endpoint{ nicid: nicid, - id: stack.NetworkEndpointID{LocalAddress: addr}, + id: stack.NetworkEndpointID{LocalAddress: addrWithPrefix.Address}, + prefixLen: addrWithPrefix.PrefixLen, linkEP: linkEP, linkAddrCache: linkAddrCache, dispatcher: dispatcher, diff --git a/pkg/tcpip/stack/nic.go b/pkg/tcpip/stack/nic.go index 30c0dee42..3e6ff4afb 100644 --- a/pkg/tcpip/stack/nic.go +++ b/pkg/tcpip/stack/nic.go @@ -129,7 +129,7 @@ func (n *NIC) setSpoofing(enable bool) { n.mu.Unlock() } -func (n *NIC) getMainNICAddress(protocol tcpip.NetworkProtocolNumber) (tcpip.Address, tcpip.Subnet, *tcpip.Error) { +func (n *NIC) getMainNICAddress(protocol tcpip.NetworkProtocolNumber) (tcpip.AddressWithPrefix, *tcpip.Error) { n.mu.RLock() defer n.mu.RUnlock() @@ -148,21 +148,16 @@ func (n *NIC) getMainNICAddress(protocol tcpip.NetworkProtocolNumber) (tcpip.Add } if r == nil { - return "", tcpip.Subnet{}, tcpip.ErrNoLinkAddress + return tcpip.AddressWithPrefix{}, tcpip.ErrNoLinkAddress } - address := r.ep.ID().LocalAddress + addressWithPrefix := tcpip.AddressWithPrefix{ + Address: r.ep.ID().LocalAddress, + PrefixLen: r.ep.PrefixLen(), + } r.decRef() - // Find the least-constrained matching subnet for the address, if one - // exists, and return it. - var subnet tcpip.Subnet - for _, s := range n.subnets { - if s.Contains(address) && !subnet.Contains(s.ID()) { - subnet = s - } - } - return address, subnet, nil + return addressWithPrefix, nil } // primaryEndpoint returns the primary endpoint of n for the given network @@ -213,23 +208,26 @@ func (n *NIC) findEndpoint(protocol tcpip.NetworkProtocolNumber, address tcpip.A n.mu.Lock() ref = n.endpoints[id] if ref == nil || !ref.tryIncRef() { - ref, _ = n.addAddressLocked(protocol, address, peb, true) - if ref != nil { - ref.holdsInsertRef = false + if netProto, ok := n.stack.networkProtocols[protocol]; ok { + addrWithPrefix := tcpip.AddressWithPrefix{address, netProto.DefaultPrefixLen()} + ref, _ = n.addAddressLocked(protocol, addrWithPrefix, peb, true) + if ref != nil { + ref.holdsInsertRef = false + } } } n.mu.Unlock() return ref } -func (n *NIC) addAddressLocked(protocol tcpip.NetworkProtocolNumber, addr tcpip.Address, peb PrimaryEndpointBehavior, replace bool) (*referencedNetworkEndpoint, *tcpip.Error) { +func (n *NIC) addAddressLocked(protocol tcpip.NetworkProtocolNumber, addrWithPrefix tcpip.AddressWithPrefix, peb PrimaryEndpointBehavior, replace bool) (*referencedNetworkEndpoint, *tcpip.Error) { netProto, ok := n.stack.networkProtocols[protocol] if !ok { return nil, tcpip.ErrUnknownProtocol } // Create the new network endpoint. - ep, err := netProto.NewEndpoint(n.id, addr, n.stack, n, n.linkEP) + ep, err := netProto.NewEndpoint(n.id, addrWithPrefix, n.stack, n, n.linkEP) if err != nil { return nil, err } @@ -278,16 +276,10 @@ func (n *NIC) addAddressLocked(protocol tcpip.NetworkProtocolNumber, addr tcpip. // AddAddress adds a new address to n, so that it starts accepting packets // targeted at the given address (and network protocol). -func (n *NIC) AddAddress(protocol tcpip.NetworkProtocolNumber, addr tcpip.Address) *tcpip.Error { - return n.AddAddressWithOptions(protocol, addr, CanBePrimaryEndpoint) -} - -// AddAddressWithOptions is the same as AddAddress, but allows you to specify -// whether the new endpoint can be primary or not. -func (n *NIC) AddAddressWithOptions(protocol tcpip.NetworkProtocolNumber, addr tcpip.Address, peb PrimaryEndpointBehavior) *tcpip.Error { +func (n *NIC) AddAddress(protocol tcpip.NetworkProtocolNumber, addrWithPrefix tcpip.AddressWithPrefix, peb PrimaryEndpointBehavior) *tcpip.Error { // Add the endpoint. n.mu.Lock() - _, err := n.addAddressLocked(protocol, addr, peb, false) + _, err := n.addAddressLocked(protocol, addrWithPrefix, peb, false) n.mu.Unlock() return err @@ -298,10 +290,13 @@ func (n *NIC) Addresses() []tcpip.ProtocolAddress { n.mu.RLock() defer n.mu.RUnlock() addrs := make([]tcpip.ProtocolAddress, 0, len(n.endpoints)) - for nid, ep := range n.endpoints { + for nid, ref := range n.endpoints { addrs = append(addrs, tcpip.ProtocolAddress{ - Protocol: ep.protocol, - Address: nid.LocalAddress, + Protocol: ref.protocol, + AddressWithPrefix: tcpip.AddressWithPrefix{ + Address: nid.LocalAddress, + PrefixLen: ref.ep.PrefixLen(), + }, }) } return addrs @@ -415,7 +410,12 @@ func (n *NIC) joinGroup(protocol tcpip.NetworkProtocolNumber, addr tcpip.Address id := NetworkEndpointID{addr} joins := n.mcastJoins[id] if joins == 0 { - if _, err := n.addAddressLocked(protocol, addr, NeverPrimaryEndpoint, false); err != nil { + netProto, ok := n.stack.networkProtocols[protocol] + if !ok { + return tcpip.ErrUnknownProtocol + } + addrWithPrefix := tcpip.AddressWithPrefix{addr, netProto.DefaultPrefixLen()} + if _, err := n.addAddressLocked(protocol, addrWithPrefix, NeverPrimaryEndpoint, false); err != nil { return err } } @@ -572,7 +572,13 @@ func (n *NIC) getRef(protocol tcpip.NetworkProtocolNumber, dst tcpip.Address) *r n.mu.Unlock() return ref } - ref, err := n.addAddressLocked(protocol, dst, CanBePrimaryEndpoint, true) + netProto, ok := n.stack.networkProtocols[protocol] + if !ok { + n.mu.Unlock() + return nil + } + addrWithPrefix := tcpip.AddressWithPrefix{dst, netProto.DefaultPrefixLen()} + ref, err := n.addAddressLocked(protocol, addrWithPrefix, CanBePrimaryEndpoint, true) n.mu.Unlock() if err == nil { ref.holdsInsertRef = false diff --git a/pkg/tcpip/stack/registration.go b/pkg/tcpip/stack/registration.go index 462265281..2037eef9f 100644 --- a/pkg/tcpip/stack/registration.go +++ b/pkg/tcpip/stack/registration.go @@ -181,6 +181,9 @@ type NetworkEndpoint interface { // ID returns the network protocol endpoint ID. ID() *NetworkEndpointID + // PrefixLen returns the network endpoint's subnet prefix length in bits. + PrefixLen() int + // NICID returns the id of the NIC this endpoint belongs to. NICID() tcpip.NICID @@ -203,12 +206,15 @@ type NetworkProtocol interface { // than this targeted at this protocol. MinimumPacketSize() int + // DefaultPrefixLen returns the protocol's default prefix length. + DefaultPrefixLen() int + // ParsePorts returns the source and destination addresses stored in a // packet of this protocol. ParseAddresses(v buffer.View) (src, dst tcpip.Address) // NewEndpoint creates a new endpoint of this protocol. - NewEndpoint(nicid tcpip.NICID, addr tcpip.Address, linkAddrCache LinkAddressCache, dispatcher TransportDispatcher, sender LinkEndpoint) (NetworkEndpoint, *tcpip.Error) + NewEndpoint(nicid tcpip.NICID, addrWithPrefix tcpip.AddressWithPrefix, linkAddrCache LinkAddressCache, dispatcher TransportDispatcher, sender LinkEndpoint) (NetworkEndpoint, *tcpip.Error) // SetOption allows enabling/disabling protocol specific features. // SetOption returns an error if the option is not supported or the diff --git a/pkg/tcpip/stack/stack.go b/pkg/tcpip/stack/stack.go index 3e8fb2a6c..57b8a9994 100644 --- a/pkg/tcpip/stack/stack.go +++ b/pkg/tcpip/stack/stack.go @@ -751,9 +751,26 @@ func (s *Stack) AddAddress(id tcpip.NICID, protocol tcpip.NetworkProtocolNumber, return s.AddAddressWithOptions(id, protocol, addr, CanBePrimaryEndpoint) } +// AddAddressWithPrefix adds a new network-layer address/prefixLen to the +// specified NIC. +func (s *Stack) AddAddressWithPrefix(id tcpip.NICID, protocol tcpip.NetworkProtocolNumber, addrWithPrefix tcpip.AddressWithPrefix) *tcpip.Error { + return s.AddAddressWithPrefixAndOptions(id, protocol, addrWithPrefix, CanBePrimaryEndpoint) +} + // AddAddressWithOptions is the same as AddAddress, but allows you to specify // whether the new endpoint can be primary or not. func (s *Stack) AddAddressWithOptions(id tcpip.NICID, protocol tcpip.NetworkProtocolNumber, addr tcpip.Address, peb PrimaryEndpointBehavior) *tcpip.Error { + netProto, ok := s.networkProtocols[protocol] + if !ok { + return tcpip.ErrUnknownProtocol + } + addrWithPrefix := tcpip.AddressWithPrefix{addr, netProto.DefaultPrefixLen()} + return s.AddAddressWithPrefixAndOptions(id, protocol, addrWithPrefix, peb) +} + +// AddAddressWithPrefixAndOptions is the same as AddAddressWithPrefixLen, +// but allows you to specify whether the new endpoint can be primary or not. +func (s *Stack) AddAddressWithPrefixAndOptions(id tcpip.NICID, protocol tcpip.NetworkProtocolNumber, addrWithPrefix tcpip.AddressWithPrefix, peb PrimaryEndpointBehavior) *tcpip.Error { s.mu.RLock() defer s.mu.RUnlock() @@ -762,7 +779,7 @@ func (s *Stack) AddAddressWithOptions(id tcpip.NICID, protocol tcpip.NetworkProt return tcpip.ErrUnknownNICID } - return nic.AddAddressWithOptions(protocol, addr, peb) + return nic.AddAddress(protocol, addrWithPrefix, peb) } // AddSubnet adds a subnet range to the specified NIC. @@ -821,7 +838,7 @@ func (s *Stack) RemoveAddress(id tcpip.NICID, addr tcpip.Address) *tcpip.Error { // contains it) for the given NIC and protocol. Returns an arbitrary endpoint's // address if no primary addresses exist. Returns an error if the NIC doesn't // exist or has no endpoints. -func (s *Stack) GetMainNICAddress(id tcpip.NICID, protocol tcpip.NetworkProtocolNumber) (tcpip.Address, tcpip.Subnet, *tcpip.Error) { +func (s *Stack) GetMainNICAddress(id tcpip.NICID, protocol tcpip.NetworkProtocolNumber) (tcpip.AddressWithPrefix, *tcpip.Error) { s.mu.RLock() defer s.mu.RUnlock() @@ -829,7 +846,7 @@ func (s *Stack) GetMainNICAddress(id tcpip.NICID, protocol tcpip.NetworkProtocol return nic.getMainNICAddress(protocol) } - return "", tcpip.Subnet{}, tcpip.ErrUnknownNICID + return tcpip.AddressWithPrefix{}, tcpip.ErrUnknownNICID } func (s *Stack) getRefEP(nic *NIC, localAddr tcpip.Address, netProto tcpip.NetworkProtocolNumber) (ref *referencedNetworkEndpoint) { diff --git a/pkg/tcpip/tcpip.go b/pkg/tcpip/tcpip.go index c5d79da5e..4208c0303 100644 --- a/pkg/tcpip/tcpip.go +++ b/pkg/tcpip/tcpip.go @@ -1059,14 +1059,23 @@ func ParseMACAddress(s string) (LinkAddress, error) { return LinkAddress(addr), nil } +// AddressWithPrefix is an address with its subnet prefix length. +type AddressWithPrefix struct { + // Address is a network address. + Address Address + + // PrefixLen is the subnet prefix length. + PrefixLen int +} + // ProtocolAddress is an address and the network protocol it is associated // with. type ProtocolAddress struct { // Protocol is the protocol of the address. Protocol NetworkProtocolNumber - // Address is a network address. - Address Address + // AddressWithPrefix is a network address with its subnet prefix length. + AddressWithPrefix AddressWithPrefix } // danglingEndpointsMu protects access to danglingEndpoints. |