Merge release-20210301.0-18-g498709250 (automated)
This commit is contained in:
commit
c72f163bca
|
@ -232,7 +232,7 @@ func (e *endpoint) HandlePacket(pkt *stack.PacketBuffer) {
|
|||
linkAddr := tcpip.LinkAddress(h.HardwareAddressSender())
|
||||
|
||||
e.mu.Lock()
|
||||
e.mu.dad.StopLocked(addr, &stack.DADDupAddrDetected{})
|
||||
e.mu.dad.StopLocked(addr, &stack.DADDupAddrDetected{HolderLinkAddress: linkAddr})
|
||||
e.mu.Unlock()
|
||||
|
||||
// The solicited, override, and isRouter flags are not available for ARP;
|
||||
|
|
|
@ -382,6 +382,10 @@ func (e *endpoint) handleICMP(pkt *stack.PacketBuffer, hasFragmentHeader bool, r
|
|||
// stack know so it can handle such a scenario and do nothing further with
|
||||
// the NS.
|
||||
if srcAddr == header.IPv6Any {
|
||||
// Since this is a DAD message we know the sender does not actually hold
|
||||
// the target address so there is no "holder".
|
||||
var holderLinkAddress tcpip.LinkAddress
|
||||
|
||||
// We would get an error if the address no longer exists or the address
|
||||
// is no longer tentative (DAD resolved between the call to
|
||||
// hasTentativeAddr and this point). Both of these are valid scenarios:
|
||||
|
@ -393,7 +397,7 @@ func (e *endpoint) handleICMP(pkt *stack.PacketBuffer, hasFragmentHeader bool, r
|
|||
//
|
||||
// TODO(gvisor.dev/issue/4046): Handle the scenario when a duplicate
|
||||
// address is detected for an assigned address.
|
||||
switch err := e.dupTentativeAddrDetected(targetAddr); err.(type) {
|
||||
switch err := e.dupTentativeAddrDetected(targetAddr, holderLinkAddress); err.(type) {
|
||||
case nil, *tcpip.ErrBadAddress, *tcpip.ErrInvalidEndpointState:
|
||||
default:
|
||||
panic(fmt.Sprintf("unexpected error handling duplicate tentative address: %s", err))
|
||||
|
@ -561,10 +565,24 @@ func (e *endpoint) handleICMP(pkt *stack.PacketBuffer, hasFragmentHeader bool, r
|
|||
// 5, NDP messages cannot be fragmented. Also note that in the common case
|
||||
// NDP datagrams are very small and AsView() will not incur allocations.
|
||||
na := header.NDPNeighborAdvert(payload.AsView())
|
||||
|
||||
it, err := na.Options().Iter(false /* check */)
|
||||
if err != nil {
|
||||
// If we have a malformed NDP NA option, drop the packet.
|
||||
received.invalid.Increment()
|
||||
return
|
||||
}
|
||||
|
||||
targetLinkAddr, ok := getTargetLinkAddr(it)
|
||||
if !ok {
|
||||
received.invalid.Increment()
|
||||
return
|
||||
}
|
||||
|
||||
targetAddr := na.TargetAddress()
|
||||
|
||||
e.dad.mu.Lock()
|
||||
e.dad.mu.dad.StopLocked(targetAddr, &stack.DADDupAddrDetected{})
|
||||
e.dad.mu.dad.StopLocked(targetAddr, &stack.DADDupAddrDetected{HolderLinkAddress: targetLinkAddr})
|
||||
e.dad.mu.Unlock()
|
||||
|
||||
if e.hasTentativeAddr(targetAddr) {
|
||||
|
@ -584,7 +602,7 @@ func (e *endpoint) handleICMP(pkt *stack.PacketBuffer, hasFragmentHeader bool, r
|
|||
//
|
||||
// TODO(gvisor.dev/issue/4046): Handle the scenario when a duplicate
|
||||
// address is detected for an assigned address.
|
||||
switch err := e.dupTentativeAddrDetected(targetAddr); err.(type) {
|
||||
switch err := e.dupTentativeAddrDetected(targetAddr, targetLinkAddr); err.(type) {
|
||||
case nil, *tcpip.ErrBadAddress, *tcpip.ErrInvalidEndpointState:
|
||||
return
|
||||
default:
|
||||
|
@ -592,13 +610,6 @@ func (e *endpoint) handleICMP(pkt *stack.PacketBuffer, hasFragmentHeader bool, r
|
|||
}
|
||||
}
|
||||
|
||||
it, err := na.Options().Iter(false /* check */)
|
||||
if err != nil {
|
||||
// If we have a malformed NDP NA option, drop the packet.
|
||||
received.invalid.Increment()
|
||||
return
|
||||
}
|
||||
|
||||
// At this point we know that the target address is not tentative on the
|
||||
// NIC. However, the target address may still be assigned to the NIC but not
|
||||
// tentative (it could be permanent). Such a scenario is beyond the scope of
|
||||
|
@ -608,11 +619,6 @@ func (e *endpoint) handleICMP(pkt *stack.PacketBuffer, hasFragmentHeader bool, r
|
|||
// TODO(b/143147598): Handle the scenario described above. Also inform the
|
||||
// netstack integration that a duplicate address was detected outside of
|
||||
// DAD.
|
||||
targetLinkAddr, ok := getTargetLinkAddr(it)
|
||||
if !ok {
|
||||
received.invalid.Increment()
|
||||
return
|
||||
}
|
||||
|
||||
// As per RFC 4861 section 7.1.2:
|
||||
// A node MUST silently discard any received Neighbor Advertisement
|
||||
|
|
|
@ -348,7 +348,7 @@ func (e *endpoint) hasTentativeAddr(addr tcpip.Address) bool {
|
|||
// dupTentativeAddrDetected removes the tentative address if it exists. If the
|
||||
// address was generated via SLAAC, an attempt is made to generate a new
|
||||
// address.
|
||||
func (e *endpoint) dupTentativeAddrDetected(addr tcpip.Address) tcpip.Error {
|
||||
func (e *endpoint) dupTentativeAddrDetected(addr tcpip.Address, holderLinkAddr tcpip.LinkAddress) tcpip.Error {
|
||||
e.mu.Lock()
|
||||
defer e.mu.Unlock()
|
||||
|
||||
|
@ -363,7 +363,7 @@ func (e *endpoint) dupTentativeAddrDetected(addr tcpip.Address) tcpip.Error {
|
|||
|
||||
// If the address is a SLAAC address, do not invalidate its SLAAC prefix as an
|
||||
// attempt will be made to generate a new address for it.
|
||||
if err := e.removePermanentEndpointLocked(addressEndpoint, false /* allowSLAACInvalidation */, &stack.DADDupAddrDetected{}); err != nil {
|
||||
if err := e.removePermanentEndpointLocked(addressEndpoint, false /* allowSLAACInvalidation */, &stack.DADDupAddrDetected{HolderLinkAddress: holderLinkAddr}); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
|
|
|
@ -884,7 +884,11 @@ func (*DADAborted) isDADResult() {}
|
|||
var _ DADResult = (*DADDupAddrDetected)(nil)
|
||||
|
||||
// DADDupAddrDetected indicates DAD detected a duplicate address.
|
||||
type DADDupAddrDetected struct{}
|
||||
type DADDupAddrDetected struct {
|
||||
// HolderLinkAddress is the link address of the node that holds the duplicate
|
||||
// address.
|
||||
HolderLinkAddress tcpip.LinkAddress
|
||||
}
|
||||
|
||||
func (*DADDupAddrDetected) isDADResult() {}
|
||||
|
||||
|
|
Loading…
Reference in New Issue