mirror of
https://github.com/netbirdio/gvisor.git
synced 2026-05-22 17:12:49 -07:00
Send unicast probes when link address is known
When the neighbor table already has link address for a neighbor but is trying to confirm reachability, it may send unicast probes to the neighbor. PiperOrigin-RevId: 336166711
This commit is contained in:
committed by
gVisor bot
parent
5124ce579d
commit
40269d0c24
@@ -646,18 +646,21 @@ func (*protocol) LinkAddressProtocol() tcpip.NetworkProtocolNumber {
|
||||
|
||||
// LinkAddressRequest implements stack.LinkAddressResolver.
|
||||
func (*protocol) LinkAddressRequest(addr, localAddr tcpip.Address, remoteLinkAddr tcpip.LinkAddress, linkEP stack.LinkEndpoint) *tcpip.Error {
|
||||
snaddr := header.SolicitedNodeAddr(addr)
|
||||
|
||||
// TODO(b/148672031): Use stack.FindRoute instead of manually creating the
|
||||
// route here. Note, we would need the nicID to do this properly so the right
|
||||
// NIC (associated to linkEP) is used to send the NDP NS message.
|
||||
r := &stack.Route{
|
||||
r := stack.Route{
|
||||
LocalAddress: localAddr,
|
||||
RemoteAddress: snaddr,
|
||||
RemoteAddress: addr,
|
||||
RemoteLinkAddress: remoteLinkAddr,
|
||||
}
|
||||
|
||||
// If a remote address is not already known, then send a multicast
|
||||
// solicitation since multicast addresses have a static mapping to link
|
||||
// addresses.
|
||||
if len(r.RemoteLinkAddress) == 0 {
|
||||
r.RemoteLinkAddress = header.EthernetAddressFromMulticastIPv6Address(snaddr)
|
||||
r.RemoteAddress = header.SolicitedNodeAddr(addr)
|
||||
r.RemoteLinkAddress = header.EthernetAddressFromMulticastIPv6Address(r.RemoteAddress)
|
||||
}
|
||||
|
||||
pkt := stack.NewPacketBuffer(stack.PacketBufferOptions{
|
||||
@@ -683,7 +686,7 @@ func (*protocol) LinkAddressRequest(addr, localAddr tcpip.Address, remoteLinkAdd
|
||||
})
|
||||
|
||||
// TODO(stijlist): count this in ICMP stats.
|
||||
return linkEP.WritePacket(r, nil /* gso */, ProtocolNumber, pkt)
|
||||
return linkEP.WritePacket(&r, nil /* gso */, ProtocolNumber, pkt)
|
||||
}
|
||||
|
||||
// ResolveStaticAddress implements stack.LinkAddressResolver.
|
||||
|
||||
@@ -22,6 +22,7 @@ import (
|
||||
|
||||
"gvisor.dev/gvisor/pkg/tcpip"
|
||||
"gvisor.dev/gvisor/pkg/tcpip/buffer"
|
||||
"gvisor.dev/gvisor/pkg/tcpip/checker"
|
||||
"gvisor.dev/gvisor/pkg/tcpip/header"
|
||||
"gvisor.dev/gvisor/pkg/tcpip/link/channel"
|
||||
"gvisor.dev/gvisor/pkg/tcpip/link/sniffer"
|
||||
@@ -1223,19 +1224,22 @@ func TestLinkAddressRequest(t *testing.T) {
|
||||
mcaddr := header.EthernetAddressFromMulticastIPv6Address(snaddr)
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
remoteLinkAddr tcpip.LinkAddress
|
||||
expectLinkAddr tcpip.LinkAddress
|
||||
name string
|
||||
remoteLinkAddr tcpip.LinkAddress
|
||||
expectedLinkAddr tcpip.LinkAddress
|
||||
expectedAddr tcpip.Address
|
||||
}{
|
||||
{
|
||||
name: "Unicast",
|
||||
remoteLinkAddr: linkAddr1,
|
||||
expectLinkAddr: linkAddr1,
|
||||
name: "Unicast",
|
||||
remoteLinkAddr: linkAddr1,
|
||||
expectedLinkAddr: linkAddr1,
|
||||
expectedAddr: lladdr0,
|
||||
},
|
||||
{
|
||||
name: "Multicast",
|
||||
remoteLinkAddr: "",
|
||||
expectLinkAddr: mcaddr,
|
||||
name: "Multicast",
|
||||
remoteLinkAddr: "",
|
||||
expectedLinkAddr: mcaddr,
|
||||
expectedAddr: snaddr,
|
||||
},
|
||||
}
|
||||
|
||||
@@ -1258,9 +1262,22 @@ func TestLinkAddressRequest(t *testing.T) {
|
||||
if !ok {
|
||||
t.Fatal("expected to send a link address request")
|
||||
}
|
||||
|
||||
if got, want := pkt.Route.RemoteLinkAddress, test.expectLinkAddr; got != want {
|
||||
t.Errorf("got pkt.Route.RemoteLinkAddress = %s, want = %s", got, want)
|
||||
if pkt.Route.RemoteLinkAddress != test.expectedLinkAddr {
|
||||
t.Errorf("got pkt.Route.RemoteLinkAddress = %s, want = %s", pkt.Route.RemoteLinkAddress, test.expectedLinkAddr)
|
||||
}
|
||||
if pkt.Route.RemoteAddress != test.expectedAddr {
|
||||
t.Errorf("got pkt.Route.RemoteAddress = %s, want = %s", pkt.Route.RemoteAddress, test.expectedAddr)
|
||||
}
|
||||
if pkt.Route.LocalAddress != lladdr1 {
|
||||
t.Errorf("got pkt.Route.LocalAddress = %s, want = %s", pkt.Route.LocalAddress, lladdr1)
|
||||
}
|
||||
checker.IPv6(t, stack.PayloadSince(pkt.Pkt.NetworkHeader()),
|
||||
checker.SrcAddr(lladdr1),
|
||||
checker.DstAddr(test.expectedAddr),
|
||||
checker.TTL(header.NDPHopLimit),
|
||||
checker.NDPNS(
|
||||
checker.NDPNSTargetAddress(lladdr0),
|
||||
checker.NDPNSOptions([]header.NDPOption{header.NDPSourceLinkLayerAddressOption(linkAddr0)}),
|
||||
))
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user