diff --git a/pkg/tcpip/network/ipv6/BUILD b/pkg/tcpip/network/ipv6/BUILD index 8b57d808c..60efd669e 100644 --- a/pkg/tcpip/network/ipv6/BUILD +++ b/pkg/tcpip/network/ipv6/BUILD @@ -23,7 +23,6 @@ go_library( "//pkg/tcpip", "//pkg/tcpip/header", "//pkg/tcpip/header/parse", - "//pkg/tcpip/network/hash", "//pkg/tcpip/network/internal/fragmentation", "//pkg/tcpip/network/internal/ip", "//pkg/tcpip/network/internal/multicast", diff --git a/pkg/tcpip/network/ipv6/ipv6.go b/pkg/tcpip/network/ipv6/ipv6.go index 21eaec105..e8d02ea6b 100644 --- a/pkg/tcpip/network/ipv6/ipv6.go +++ b/pkg/tcpip/network/ipv6/ipv6.go @@ -16,9 +16,7 @@ package ipv6 import ( - "encoding/binary" "fmt" - "hash/fnv" "math" "reflect" "sort" @@ -30,7 +28,6 @@ import ( "gvisor.dev/gvisor/pkg/tcpip" "gvisor.dev/gvisor/pkg/tcpip/header" "gvisor.dev/gvisor/pkg/tcpip/header/parse" - "gvisor.dev/gvisor/pkg/tcpip/network/hash" "gvisor.dev/gvisor/pkg/tcpip/network/internal/fragmentation" "gvisor.dev/gvisor/pkg/tcpip/network/internal/ip" "gvisor.dev/gvisor/pkg/tcpip/network/internal/multicast" @@ -777,7 +774,7 @@ func (e *endpoint) handleFragments(r *stack.Route, networkMTU uint32, pkt stack. pf := fragmentation.MakePacketFragmenter(pkt, fragmentPayloadLen, calculateFragmentReserve(pkt)) defer pf.Release() - id := e.protocol.ids[hashRoute(r, e.protocol.hashIV)%buckets].Add(1) + id := e.getFragmentID() var n int for { @@ -2288,9 +2285,6 @@ type protocol struct { multicastForwardingDisp stack.MulticastForwardingEventDispatcher } - ids []atomicbitops.Uint32 - hashIV uint32 - // defaultTTL is the current default TTL for the protocol. Only the // uint8 portion of it is meaningful. defaultTTL atomicbitops.Uint32 @@ -2749,21 +2743,10 @@ type Options struct { func NewProtocolWithOptions(opts Options) stack.NetworkProtocolFactory { opts.NDPConfigs.validate() - ids := hash.RandN32(buckets) - hashIV := hash.RandN32(1)[0] - - atomicIds := make([]atomicbitops.Uint32, len(ids)) - for i := range ids { - atomicIds[i] = atomicbitops.FromUint32(ids[i]) - } - return func(s *stack.Stack) stack.NetworkProtocol { p := &protocol{ stack: s, options: opts, - - ids: atomicIds, - hashIV: hashIV, } p.fragmentation = fragmentation.NewFragmentation(header.IPv6FragmentExtHdrFragmentOffsetBytesPerUnit, fragmentation.HighFragThreshold, fragmentation.LowFragThreshold, ReassembleTimeout, s.Clock(), p) p.mu.eps = make(map[tcpip.NICID]*endpoint) @@ -2800,28 +2783,15 @@ func calculateFragmentReserve(pkt stack.PacketBufferPtr) int { return pkt.AvailableHeaderBytes() + len(pkt.NetworkHeader().Slice()) + header.IPv6FragmentHeaderSize } -// hashRoute calculates a hash value for the given route. It uses the source & -// destination address and 32-bit number to generate the hash. -func hashRoute(r *stack.Route, hashIV uint32) uint32 { - // The FNV-1a was chosen because it is a fast hashing algorithm, and - // cryptographic properties are not needed here. - h := fnv.New32a() - localAddr := r.LocalAddress() - if _, err := h.Write(localAddr.AsSlice()); err != nil { - panic(fmt.Sprintf("Hash.Write: %s, but Hash' implementation of Write is not expected to ever return an error", err)) +// getFragmentID returns a random uint32 number (other than zero) to be used as +// fragment ID in the IPv6 header. +func (e *endpoint) getFragmentID() uint32 { + rng := e.protocol.stack.SecureRNG() + id := rng.Uint32() + for id == 0 { + id = rng.Uint32() } - remoteAddr := r.RemoteAddress() - if _, err := h.Write(remoteAddr.AsSlice()); err != nil { - panic(fmt.Sprintf("Hash.Write: %s, but Hash' implementation of Write is not expected to ever return an error", err)) - } - - s := make([]byte, 4) - binary.LittleEndian.PutUint32(s, hashIV) - if _, err := h.Write(s); err != nil { - panic(fmt.Sprintf("Hash.Write: %s, but Hash' implementation of Write is not expected ever to return an error", err)) - } - - return h.Sum32() + return id } func buildNextFragment(pf *fragmentation.PacketFragmenter, originalIPHeaders header.IPv6, transportProto tcpip.TransportProtocolNumber, id uint32) (stack.PacketBufferPtr, bool) {