summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--pkg/tcpip/link/channel/channel.go6
-rw-r--r--pkg/tcpip/link/sniffer/sniffer.go31
-rw-r--r--pkg/tcpip/network/ipv4/ipv4.go2
-rw-r--r--pkg/tcpip/network/ipv6/BUILD19
-rw-r--r--pkg/tcpip/network/ipv6/icmp.go137
-rw-r--r--pkg/tcpip/network/ipv6/icmp_test.go236
-rw-r--r--pkg/tcpip/network/ipv6/ipv6.go30
-rw-r--r--pkg/tcpip/stack/nic.go2
-rw-r--r--pkg/tcpip/transport/ping/endpoint.go38
-rw-r--r--pkg/tcpip/transport/ping/protocol.go16
10 files changed, 27 insertions, 490 deletions
diff --git a/pkg/tcpip/link/channel/channel.go b/pkg/tcpip/link/channel/channel.go
index dd3fe7c87..9d69f1d45 100644
--- a/pkg/tcpip/link/channel/channel.go
+++ b/pkg/tcpip/link/channel/channel.go
@@ -71,12 +71,6 @@ func (e *Endpoint) Inject(protocol tcpip.NetworkProtocolNumber, vv *buffer.Vecto
e.dispatcher.DeliverNetworkPacket(e, "", protocol, &uu)
}
-// InjectLinkAddr injects an inbound packet with a remote link address.
-func (e *Endpoint) InjectLinkAddr(protocol tcpip.NetworkProtocolNumber, remoteLinkAddr tcpip.LinkAddress, vv *buffer.VectorisedView) {
- uu := vv.Clone(nil)
- e.dispatcher.DeliverNetworkPacket(e, remoteLinkAddr, protocol, &uu)
-}
-
// Attach saves the stack network-layer dispatcher for use later when packets
// are injected.
func (e *Endpoint) Attach(dispatcher stack.NetworkDispatcher) {
diff --git a/pkg/tcpip/link/sniffer/sniffer.go b/pkg/tcpip/link/sniffer/sniffer.go
index 1e302f557..414a7edb4 100644
--- a/pkg/tcpip/link/sniffer/sniffer.go
+++ b/pkg/tcpip/link/sniffer/sniffer.go
@@ -303,37 +303,6 @@ func logPacket(prefix string, protocol tcpip.NetworkProtocolNumber, b, plb []byt
log.Infof("%s %s %v -> %v %s len:%d id:%04x code:%d", prefix, transName, src, dst, icmpType, size, id, icmp.Code())
return
- case header.ICMPv6ProtocolNumber:
- transName = "icmp"
- icmp := header.ICMPv6(b)
- icmpType := "unknown"
- switch icmp.Type() {
- case header.ICMPv6DstUnreachable:
- icmpType = "destination unreachable"
- case header.ICMPv6PacketTooBig:
- icmpType = "packet too big"
- case header.ICMPv6TimeExceeded:
- icmpType = "time exceeded"
- case header.ICMPv6ParamProblem:
- icmpType = "param problem"
- case header.ICMPv6EchoRequest:
- icmpType = "echo request"
- case header.ICMPv6EchoReply:
- icmpType = "echo reply"
- case header.ICMPv6RouterSolicit:
- icmpType = "router solicit"
- case header.ICMPv6RouterAdvert:
- icmpType = "router advert"
- case header.ICMPv6NeighborSolicit:
- icmpType = "neighbor solicit"
- case header.ICMPv6NeighborAdvert:
- icmpType = "neighbor advert"
- case header.ICMPv6RedirectMsg:
- icmpType = "redirect message"
- }
- log.Infof("%s %s %v -> %v %s len:%d id:%04x code:%d", prefix, transName, src, dst, icmpType, size, id, icmp.Code())
- return
-
case header.UDPProtocolNumber:
transName = "udp"
udp := header.UDP(b)
diff --git a/pkg/tcpip/network/ipv4/ipv4.go b/pkg/tcpip/network/ipv4/ipv4.go
index 512ef0d60..e6b1f5128 100644
--- a/pkg/tcpip/network/ipv4/ipv4.go
+++ b/pkg/tcpip/network/ipv4/ipv4.go
@@ -67,7 +67,7 @@ func newEndpoint(nicid tcpip.NICID, addr tcpip.Address, dispatcher stack.Transpo
fragmentation: fragmentation.NewFragmentation(fragmentation.HighFragThreshold, fragmentation.LowFragThreshold, fragmentation.DefaultReassembleTimeout),
}
copy(e.address[:], addr)
- e.id = stack.NetworkEndpointID{LocalAddress: tcpip.Address(e.address[:])}
+ e.id = stack.NetworkEndpointID{tcpip.Address(e.address[:])}
go e.echoReplier()
diff --git a/pkg/tcpip/network/ipv6/BUILD b/pkg/tcpip/network/ipv6/BUILD
index 2f19a659e..1c3eccae0 100644
--- a/pkg/tcpip/network/ipv6/BUILD
+++ b/pkg/tcpip/network/ipv6/BUILD
@@ -1,6 +1,6 @@
package(licenses = ["notice"]) # Apache 2.0
-load("//tools/go_stateify:defs.bzl", "go_library", "go_test")
+load("//tools/go_stateify:defs.bzl", "go_library")
go_library(
name = "ipv6",
@@ -19,20 +19,3 @@ go_library(
"//pkg/tcpip/stack",
],
)
-
-go_test(
- name = "ipv6_test",
- size = "small",
- srcs = ["icmp_test.go"],
- embed = [":ipv6"],
- deps = [
- "//pkg/tcpip",
- "//pkg/tcpip/buffer",
- "//pkg/tcpip/header",
- "//pkg/tcpip/link/channel",
- "//pkg/tcpip/link/sniffer",
- "//pkg/tcpip/stack",
- "//pkg/tcpip/transport/ping",
- "//pkg/waiter",
- ],
-)
diff --git a/pkg/tcpip/network/ipv6/icmp.go b/pkg/tcpip/network/ipv6/icmp.go
index 6db004baa..8b8539def 100644
--- a/pkg/tcpip/network/ipv6/icmp.go
+++ b/pkg/tcpip/network/ipv6/icmp.go
@@ -17,7 +17,6 @@ package ipv6
import (
"encoding/binary"
- "gvisor.googlesource.com/gvisor/pkg/tcpip"
"gvisor.googlesource.com/gvisor/pkg/tcpip/buffer"
"gvisor.googlesource.com/gvisor/pkg/tcpip/header"
"gvisor.googlesource.com/gvisor/pkg/tcpip/stack"
@@ -87,141 +86,5 @@ func (e *endpoint) handleICMP(r *stack.Route, vv *buffer.VectorisedView) {
case header.ICMPv6PortUnreachable:
e.handleControl(stack.ControlPortUnreachable, 0, vv)
}
-
- case header.ICMPv6NeighborSolicit:
- if len(v) < header.ICMPv6NeighborSolicitMinimumSize {
- return
- }
- targetAddr := tcpip.Address(v[8 : 8+16])
- if e.linkAddrCache.CheckLocalAddress(e.nicid, ProtocolNumber, targetAddr) == 0 {
- // We don't have a useful answer; the best we can do is ignore the request.
- return
- }
- hdr := buffer.NewPrependable(int(r.MaxHeaderLength()) + header.IPv6MinimumSize + header.ICMPv6NeighborAdvertSize)
- pkt := header.ICMPv6(hdr.Prepend(header.ICMPv6NeighborAdvertSize))
- pkt.SetType(header.ICMPv6NeighborAdvert)
- pkt[icmpV6FlagOffset] = ndpSolicitedFlag | ndpOverrideFlag
- copy(pkt[icmpV6OptOffset-len(targetAddr):], targetAddr)
- pkt[icmpV6OptOffset] = ndpOptDstLinkAddr
- pkt[icmpV6LengthOffset] = 1
- copy(pkt[icmpV6LengthOffset+1:], r.LocalLinkAddress[:])
- pkt.SetChecksum(icmpChecksum(pkt, r.LocalAddress, r.RemoteAddress, nil))
- r.WritePacket(&hdr, nil, header.ICMPv6ProtocolNumber)
-
- e.linkAddrCache.AddLinkAddress(e.nicid, r.RemoteAddress, r.RemoteLinkAddress)
-
- case header.ICMPv6NeighborAdvert:
- if len(v) < header.ICMPv6NeighborAdvertSize {
- return
- }
- targetAddr := tcpip.Address(v[8 : 8+16])
- e.linkAddrCache.AddLinkAddress(e.nicid, targetAddr, r.RemoteLinkAddress)
- if targetAddr != r.RemoteAddress {
- e.linkAddrCache.AddLinkAddress(e.nicid, r.RemoteAddress, r.RemoteLinkAddress)
- }
-
- case header.ICMPv6EchoRequest:
- if len(v) < header.ICMPv6EchoMinimumSize {
- return
- }
- vv.TrimFront(header.ICMPv6EchoMinimumSize)
- data := vv.ToView()
- hdr := buffer.NewPrependable(int(r.MaxHeaderLength()) + header.IPv6MinimumSize + header.ICMPv6EchoMinimumSize)
- pkt := header.ICMPv6(hdr.Prepend(header.ICMPv6EchoMinimumSize))
- copy(pkt, h)
- pkt.SetType(header.ICMPv6EchoReply)
- pkt.SetChecksum(icmpChecksum(pkt, r.LocalAddress, r.RemoteAddress, data))
- r.WritePacket(&hdr, data, header.ICMPv6ProtocolNumber)
-
- case header.ICMPv6EchoReply:
- if len(v) < header.ICMPv6EchoMinimumSize {
- return
- }
- e.dispatcher.DeliverTransportPacket(r, header.ICMPv6ProtocolNumber, vv)
-
}
}
-
-const (
- ndpSolicitedFlag = 1 << 6
- ndpOverrideFlag = 1 << 5
-
- ndpOptSrcLinkAddr = 1
- ndpOptDstLinkAddr = 2
-
- icmpV6FlagOffset = 4
- icmpV6OptOffset = 24
- icmpV6LengthOffset = 25
-
- icmpV6HopLimit = 255
-)
-
-// solicitedNodeAddr computes the solicited-node multicast address.
-// This is used for NDP. Described in RFC 4291.
-func solicitedNodeAddr(addr tcpip.Address) tcpip.Address {
- const solicitedNodeMulticastPrefix = "\xff\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\xff"
- return solicitedNodeMulticastPrefix + addr[len(addr)-3:]
-}
-
-var broadcastMAC = tcpip.LinkAddress([]byte{0xff, 0xff, 0xff, 0xff, 0xff, 0xff})
-
-var _ stack.LinkAddressResolver = (*protocol)(nil)
-
-// LinkAddressProtocol implements stack.LinkAddressResolver.
-func (*protocol) LinkAddressProtocol() tcpip.NetworkProtocolNumber {
- return header.IPv6ProtocolNumber
-}
-
-// LinkAddressRequest implements stack.LinkAddressResolver.
-func (*protocol) LinkAddressRequest(addr, localAddr tcpip.Address, linkEP stack.LinkEndpoint) *tcpip.Error {
- snaddr := solicitedNodeAddr(addr)
- r := &stack.Route{
- LocalAddress: localAddr,
- RemoteAddress: snaddr,
- RemoteLinkAddress: broadcastMAC,
- }
- hdr := buffer.NewPrependable(int(linkEP.MaxHeaderLength()) + header.IPv6MinimumSize + header.ICMPv6NeighborAdvertSize)
- pkt := header.ICMPv6(hdr.Prepend(header.ICMPv6NeighborAdvertSize))
- pkt.SetType(header.ICMPv6NeighborSolicit)
- copy(pkt[icmpV6OptOffset-len(addr):], addr)
- pkt[icmpV6OptOffset] = ndpOptSrcLinkAddr
- pkt[icmpV6LengthOffset] = 1
- copy(pkt[icmpV6LengthOffset+1:], linkEP.LinkAddress())
- pkt.SetChecksum(icmpChecksum(pkt, r.LocalAddress, r.RemoteAddress, nil))
-
- length := uint16(hdr.UsedLength())
- ip := header.IPv6(hdr.Prepend(header.IPv6MinimumSize))
- ip.Encode(&header.IPv6Fields{
- PayloadLength: length,
- NextHeader: uint8(header.ICMPv6ProtocolNumber),
- HopLimit: icmpV6HopLimit,
- SrcAddr: r.LocalAddress,
- DstAddr: r.RemoteAddress,
- })
-
- return linkEP.WritePacket(r, &hdr, nil, ProtocolNumber)
-}
-
-// ResolveStaticAddress implements stack.LinkAddressResolver.
-func (*protocol) ResolveStaticAddress(addr tcpip.Address) (tcpip.LinkAddress, bool) {
- return "", false
-}
-
-func icmpChecksum(h header.ICMPv6, src, dst tcpip.Address, data []byte) uint16 {
- // Calculate the IPv6 pseudo-header upper-layer checksum.
- xsum := header.Checksum([]byte(src), 0)
- xsum = header.Checksum([]byte(dst), xsum)
- var upperLayerLength [4]byte
- binary.BigEndian.PutUint32(upperLayerLength[:], uint32(len(h)+len(data)))
- xsum = header.Checksum(upperLayerLength[:], xsum)
- xsum = header.Checksum([]byte{0, 0, 0, uint8(header.ICMPv6ProtocolNumber)}, xsum)
- xsum = header.Checksum(data, xsum)
-
- // h[2:4] is the checksum itself, set it aside to avoid checksumming the checksum.
- h2, h3 := h[2], h[3]
- h[2], h[3] = 0, 0
- xsum = ^header.Checksum(h, xsum)
- h[2], h[3] = h2, h3
-
- return xsum
-}
diff --git a/pkg/tcpip/network/ipv6/icmp_test.go b/pkg/tcpip/network/ipv6/icmp_test.go
deleted file mode 100644
index 582bbb40e..000000000
--- a/pkg/tcpip/network/ipv6/icmp_test.go
+++ /dev/null
@@ -1,236 +0,0 @@
-// Copyright 2018 Google Inc.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package ipv6
-
-import (
- "context"
- "runtime"
- "strings"
- "testing"
- "time"
-
- "gvisor.googlesource.com/gvisor/pkg/tcpip"
- "gvisor.googlesource.com/gvisor/pkg/tcpip/buffer"
- "gvisor.googlesource.com/gvisor/pkg/tcpip/header"
- "gvisor.googlesource.com/gvisor/pkg/tcpip/link/channel"
- "gvisor.googlesource.com/gvisor/pkg/tcpip/link/sniffer"
- "gvisor.googlesource.com/gvisor/pkg/tcpip/stack"
- "gvisor.googlesource.com/gvisor/pkg/tcpip/transport/ping"
- "gvisor.googlesource.com/gvisor/pkg/waiter"
-)
-
-const (
- linkAddr0 = tcpip.LinkAddress("\x01\x02\x03\x04\x05\x06")
- linkAddr1 = tcpip.LinkAddress("\x0a\x0b\x0c\x0d\x0e\x0f")
-)
-
-// linkLocalAddr computes the default IPv6 link-local address from
-// a link-layer (MAC) address.
-func linkLocalAddr(linkAddr tcpip.LinkAddress) tcpip.Address {
- // Convert a 48-bit MAC to an EUI-64 and then prepend the
- // link-local header, FE80::.
- //
- // The conversion is very nearly:
- // aa:bb:cc:dd:ee:ff => FE80::Aabb:ccFF:FEdd:eeff
- // Note the capital A. The conversion aa->Aa involves a bit flip.
- lladdrb := [16]byte{
- 0: 0xFE,
- 1: 0x80,
- 8: linkAddr[0] ^ 2,
- 9: linkAddr[1],
- 10: linkAddr[2],
- 11: 0xFF,
- 12: 0xFE,
- 13: linkAddr[3],
- 14: linkAddr[4],
- 15: linkAddr[5],
- }
- return tcpip.Address(lladdrb[:])
-}
-
-var (
- lladdr0 = linkLocalAddr(linkAddr0)
- lladdr1 = linkLocalAddr(linkAddr1)
-)
-
-type testContext struct {
- t *testing.T
- s0 *stack.Stack
- s1 *stack.Stack
-
- linkEP0 *channel.Endpoint
- linkEP1 *channel.Endpoint
-
- icmpCh chan header.ICMPv6Type
-}
-
-type endpointWithResolutionCapability struct {
- stack.LinkEndpoint
-}
-
-func (e endpointWithResolutionCapability) Capabilities() stack.LinkEndpointCapabilities {
- return e.LinkEndpoint.Capabilities() | stack.CapabilityResolutionRequired
-}
-
-func newTestContext(t *testing.T) *testContext {
- c := &testContext{
- t: t,
- s0: stack.New([]string{ProtocolName}, []string{ping.ProtocolName6}, stack.Options{}),
- s1: stack.New([]string{ProtocolName}, []string{ping.ProtocolName6}, stack.Options{}),
- icmpCh: make(chan header.ICMPv6Type, 10),
- }
-
- const defaultMTU = 65536
- _, linkEP0 := channel.New(256, defaultMTU, linkAddr0)
- c.linkEP0 = linkEP0
- wrappedEP0 := endpointWithResolutionCapability{LinkEndpoint: linkEP0}
- id0 := stack.RegisterLinkEndpoint(wrappedEP0)
- if testing.Verbose() {
- id0 = sniffer.New(id0)
- }
- if err := c.s0.CreateNIC(1, id0); err != nil {
- t.Fatalf("CreateNIC s0: %v", err)
- }
- if err := c.s0.AddAddress(1, ProtocolNumber, lladdr0); err != nil {
- t.Fatalf("AddAddress lladdr0: %v", err)
- }
- if err := c.s0.AddAddress(1, ProtocolNumber, solicitedNodeAddr(lladdr0)); err != nil {
- t.Fatalf("AddAddress sn lladdr0: %v", err)
- }
-
- _, linkEP1 := channel.New(256, defaultMTU, linkAddr1)
- c.linkEP1 = linkEP1
- wrappedEP1 := endpointWithResolutionCapability{LinkEndpoint: linkEP1}
- id1 := stack.RegisterLinkEndpoint(wrappedEP1)
- if err := c.s1.CreateNIC(1, id1); err != nil {
- t.Fatalf("CreateNIC failed: %v", err)
- }
- if err := c.s1.AddAddress(1, ProtocolNumber, lladdr1); err != nil {
- t.Fatalf("AddAddress lladdr1: %v", err)
- }
- if err := c.s1.AddAddress(1, ProtocolNumber, solicitedNodeAddr(lladdr1)); err != nil {
- t.Fatalf("AddAddress sn lladdr1: %v", err)
- }
-
- c.s0.SetRouteTable(
- []tcpip.Route{{
- Destination: lladdr1,
- Mask: tcpip.Address(strings.Repeat("\xff", 16)),
- NIC: 1,
- }},
- )
- c.s1.SetRouteTable(
- []tcpip.Route{{
- Destination: lladdr0,
- Mask: tcpip.Address(strings.Repeat("\xff", 16)),
- NIC: 1,
- }},
- )
-
- go c.routePackets(linkEP0.C, linkEP1)
- go c.routePackets(linkEP1.C, linkEP0)
-
- return c
-}
-
-func (c *testContext) countPacket(pkt channel.PacketInfo) {
- if pkt.Proto != ProtocolNumber {
- return
- }
- ipv6 := header.IPv6(pkt.Header)
- transProto := tcpip.TransportProtocolNumber(ipv6.NextHeader())
- if transProto != header.ICMPv6ProtocolNumber {
- return
- }
- b := pkt.Header[header.IPv6MinimumSize:]
- icmp := header.ICMPv6(b)
- c.icmpCh <- icmp.Type()
-}
-
-func (c *testContext) routePackets(ch <-chan channel.PacketInfo, ep *channel.Endpoint) {
- for pkt := range ch {
- c.countPacket(pkt)
- views := []buffer.View{pkt.Header, pkt.Payload}
- size := len(pkt.Header) + len(pkt.Payload)
- vv := buffer.NewVectorisedView(size, views)
- ep.InjectLinkAddr(pkt.Proto, ep.LinkAddress(), &vv)
- }
-}
-
-func (c *testContext) cleanup() {
- close(c.linkEP0.C)
- close(c.linkEP1.C)
-}
-
-func TestLinkResolution(t *testing.T) {
- c := newTestContext(t)
- defer c.cleanup()
- r, err := c.s0.FindRoute(1, lladdr0, lladdr1, ProtocolNumber)
- if err != nil {
- t.Fatal(err)
- }
- defer r.Release()
-
- hdr := buffer.NewPrependable(int(r.MaxHeaderLength()) + header.IPv6MinimumSize + header.ICMPv6EchoMinimumSize)
- pkt := header.ICMPv6(hdr.Prepend(header.ICMPv6EchoMinimumSize))
- pkt.SetType(header.ICMPv6EchoRequest)
- pkt.SetChecksum(icmpChecksum(pkt, r.LocalAddress, r.RemoteAddress, nil))
- payload := tcpip.SlicePayload(hdr.UsedBytes())
-
- // We can't send our payload directly over the route because that
- // doesn't provoke NDP discovery.
- var wq waiter.Queue
- ep, err := c.s0.NewEndpoint(header.ICMPv6ProtocolNumber, ProtocolNumber, &wq)
- if err != nil {
- t.Fatal(err)
- }
-
- // This actually takes about 10 milliseconds, so no need to wait for
- // a multi-minute go test timeout if something is broken.
- ctx, cancel := context.WithTimeout(context.Background(), 2*time.Second)
- defer cancel()
-
- for {
- if ctx.Err() != nil {
- break
- }
- if _, err := ep.Write(payload, tcpip.WriteOptions{To: &tcpip.FullAddress{NIC: 1, Addr: lladdr1}}); err == tcpip.ErrNoLinkAddress {
- // There's something asynchronous going on; yield to let it do its thing.
- runtime.Gosched()
- } else if err == nil {
- break
- } else {
- t.Fatal(err)
- }
- }
-
- stats := make(map[header.ICMPv6Type]int)
- for {
- select {
- case <-ctx.Done():
- t.Errorf("timeout waiting for ICMP, got: %#+v", stats)
- return
- case typ := <-c.icmpCh:
- stats[typ]++
-
- if stats[header.ICMPv6NeighborSolicit] > 0 &&
- stats[header.ICMPv6NeighborAdvert] > 0 &&
- stats[header.ICMPv6EchoRequest] > 0 &&
- stats[header.ICMPv6EchoReply] > 0 {
- return
- }
- }
- }
-}
diff --git a/pkg/tcpip/network/ipv6/ipv6.go b/pkg/tcpip/network/ipv6/ipv6.go
index 51d34b7ec..f48d120c5 100644
--- a/pkg/tcpip/network/ipv6/ipv6.go
+++ b/pkg/tcpip/network/ipv6/ipv6.go
@@ -42,12 +42,18 @@ const (
type address [header.IPv6AddressSize]byte
type endpoint struct {
- nicid tcpip.NICID
- id stack.NetworkEndpointID
- address address
- linkEP stack.LinkEndpoint
- linkAddrCache stack.LinkAddressCache
- dispatcher stack.TransportDispatcher
+ nicid tcpip.NICID
+ id stack.NetworkEndpointID
+ address address
+ linkEP stack.LinkEndpoint
+ dispatcher stack.TransportDispatcher
+}
+
+func newEndpoint(nicid tcpip.NICID, addr tcpip.Address, dispatcher stack.TransportDispatcher, linkEP stack.LinkEndpoint) *endpoint {
+ e := &endpoint{nicid: nicid, linkEP: linkEP, dispatcher: dispatcher}
+ copy(e.address[:], addr)
+ e.id = stack.NetworkEndpointID{tcpip.Address(e.address[:])}
+ return e
}
// MTU implements stack.NetworkEndpoint.MTU. It returns the link-layer MTU minus
@@ -87,7 +93,7 @@ func (e *endpoint) WritePacket(r *stack.Route, hdr *buffer.Prependable, payload
ip.Encode(&header.IPv6Fields{
PayloadLength: length,
NextHeader: uint8(protocol),
- HopLimit: icmpV6HopLimit,
+ HopLimit: 65,
SrcAddr: tcpip.Address(e.address[:]),
DstAddr: r.RemoteAddress,
})
@@ -148,15 +154,7 @@ 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) {
- e := &endpoint{
- nicid: nicid,
- linkEP: linkEP,
- linkAddrCache: linkAddrCache,
- dispatcher: dispatcher,
- }
- copy(e.address[:], addr)
- e.id = stack.NetworkEndpointID{LocalAddress: tcpip.Address(e.address[:])}
- return e, nil
+ return newEndpoint(nicid, addr, dispatcher, linkEP), nil
}
// SetOption implements NetworkProtocol.SetOption.
diff --git a/pkg/tcpip/stack/nic.go b/pkg/tcpip/stack/nic.go
index 77134c42a..c158e2005 100644
--- a/pkg/tcpip/stack/nic.go
+++ b/pkg/tcpip/stack/nic.go
@@ -165,7 +165,7 @@ func (n *NIC) addAddressLocked(protocol tcpip.NetworkProtocolNumber, addr tcpip.
// Set up cache if link address resolution exists for this protocol.
if n.linkEP.Capabilities()&CapabilityResolutionRequired != 0 {
- if _, ok := n.stack.linkAddrResolvers[protocol]; ok {
+ if linkRes := n.stack.linkAddrResolvers[protocol]; linkRes != nil {
ref.linkCache = n.stack
}
}
diff --git a/pkg/tcpip/transport/ping/endpoint.go b/pkg/tcpip/transport/ping/endpoint.go
index 7e10c0aae..f097ac057 100644
--- a/pkg/tcpip/transport/ping/endpoint.go
+++ b/pkg/tcpip/transport/ping/endpoint.go
@@ -56,7 +56,6 @@ type endpoint struct {
// change throughout the lifetime of the endpoint.
stack *stack.Stack `state:"manual"`
netProto tcpip.NetworkProtocolNumber
- transProto tcpip.TransportProtocolNumber
waiterQueue *waiter.Queue
// The following fields are used to manage the receive queue, and are
@@ -82,11 +81,10 @@ type endpoint struct {
route stack.Route `state:"manual"`
}
-func newEndpoint(stack *stack.Stack, netProto tcpip.NetworkProtocolNumber, transProto tcpip.TransportProtocolNumber, waiterQueue *waiter.Queue) *endpoint {
+func newEndpoint(stack *stack.Stack, netProto tcpip.NetworkProtocolNumber, waiterQueue *waiter.Queue) *endpoint {
return &endpoint{
stack: stack,
netProto: netProto,
- transProto: transProto,
waiterQueue: waiterQueue,
rcvBufSizeMax: 32 * 1024,
sndBufSize: 32 * 1024,
@@ -100,7 +98,7 @@ func (e *endpoint) Close() {
e.shutdownFlags = tcpip.ShutdownRead | tcpip.ShutdownWrite
switch e.state {
case stateBound, stateConnected:
- e.stack.UnregisterTransportEndpoint(e.regNICID, []tcpip.NetworkProtocolNumber{e.netProto}, e.transProto, e.id)
+ e.stack.UnregisterTransportEndpoint(e.regNICID, []tcpip.NetworkProtocolNumber{e.netProto}, ProtocolNumber4, e.id)
}
// Close the receive list and drain it.
@@ -299,7 +297,7 @@ func (e *endpoint) Write(p tcpip.Payload, opts tcpip.WriteOptions) (uintptr, *tc
err = sendPing4(route, e.id.LocalPort, v)
case header.IPv6ProtocolNumber:
- err = sendPing6(route, e.id.LocalPort, v)
+ // TODO: Support IPv6.
}
return uintptr(len(v)), err
@@ -387,30 +385,6 @@ func sendPing4(r *stack.Route, ident uint16, data buffer.View) *tcpip.Error {
return r.WritePacket(&hdr, data, header.ICMPv4ProtocolNumber)
}
-func sendPing6(r *stack.Route, ident uint16, data buffer.View) *tcpip.Error {
- if len(data) < header.ICMPv6EchoMinimumSize {
- return tcpip.ErrInvalidEndpointState
- }
-
- // Set the ident. Sequence number is provided by the user.
- binary.BigEndian.PutUint16(data[header.ICMPv6MinimumSize:], ident)
-
- hdr := buffer.NewPrependable(header.ICMPv6EchoMinimumSize + int(r.MaxHeaderLength()))
-
- icmpv6 := header.ICMPv6(hdr.Prepend(header.ICMPv6EchoMinimumSize))
- copy(icmpv6, data)
- data = data[header.ICMPv6EchoMinimumSize:]
-
- if icmpv6.Type() != header.ICMPv6EchoRequest || icmpv6.Code() != 0 {
- return tcpip.ErrInvalidEndpointState
- }
-
- icmpv6.SetChecksum(0)
- icmpv6.SetChecksum(^header.Checksum(icmpv6, header.Checksum(data, 0)))
-
- return r.WritePacket(&hdr, data, header.ICMPv6ProtocolNumber)
-}
-
func (e *endpoint) checkV4Mapped(addr *tcpip.FullAddress, allowMismatch bool) (tcpip.NetworkProtocolNumber, *tcpip.Error) {
netProto := e.netProto
if header.IsV4MappedAddress(addr.Addr) {
@@ -534,14 +508,14 @@ func (e *endpoint) registerWithStack(nicid tcpip.NICID, netProtos []tcpip.Networ
if id.LocalPort != 0 {
// The endpoint already has a local port, just attempt to
// register it.
- err := e.stack.RegisterTransportEndpoint(nicid, netProtos, e.transProto, id, e)
+ err := e.stack.RegisterTransportEndpoint(nicid, netProtos, ProtocolNumber4, id, e)
return id, err
}
// We need to find a port for the endpoint.
_, err := e.stack.PickEphemeralPort(func(p uint16) (bool, *tcpip.Error) {
id.LocalPort = p
- err := e.stack.RegisterTransportEndpoint(nicid, netProtos, e.transProto, id, e)
+ err := e.stack.RegisterTransportEndpoint(nicid, netProtos, ProtocolNumber4, id, e)
switch err {
case nil:
return true, nil
@@ -590,7 +564,7 @@ func (e *endpoint) bindLocked(addr tcpip.FullAddress, commit func() *tcpip.Error
if commit != nil {
if err := commit(); err != nil {
// Unregister, the commit failed.
- e.stack.UnregisterTransportEndpoint(addr.NIC, netProtos, e.transProto, id)
+ e.stack.UnregisterTransportEndpoint(addr.NIC, netProtos, ProtocolNumber4, id)
return err
}
}
diff --git a/pkg/tcpip/transport/ping/protocol.go b/pkg/tcpip/transport/ping/protocol.go
index b885f3627..8a8192064 100644
--- a/pkg/tcpip/transport/ping/protocol.go
+++ b/pkg/tcpip/transport/ping/protocol.go
@@ -71,7 +71,7 @@ func (p *protocol) NewEndpoint(stack *stack.Stack, netProto tcpip.NetworkProtoco
if netProto != p.netProto() {
return nil, tcpip.ErrUnknownProtocol
}
- return newEndpoint(stack, netProto, p.number, waiterQueue), nil
+ return newEndpoint(stack, netProto, waiterQueue), nil
}
// MinimumPacketSize returns the minimum valid ping packet size.
@@ -87,14 +87,8 @@ func (p *protocol) MinimumPacketSize() int {
// ParsePorts returns the source and destination ports stored in the given ping
// packet.
-func (p *protocol) ParsePorts(v buffer.View) (src, dst uint16, err *tcpip.Error) {
- switch p.number {
- case ProtocolNumber4:
- return 0, binary.BigEndian.Uint16(v[header.ICMPv4MinimumSize:]), nil
- case ProtocolNumber6:
- return 0, binary.BigEndian.Uint16(v[header.ICMPv6MinimumSize:]), nil
- }
- panic(fmt.Sprint("unknown protocol number: ", p.number))
+func (*protocol) ParsePorts(v buffer.View) (src, dst uint16, err *tcpip.Error) {
+ return 0, binary.BigEndian.Uint16(v[header.ICMPv4MinimumSize:]), nil
}
// HandleUnknownDestinationPacket handles packets targeted at this protocol but
@@ -118,7 +112,5 @@ func init() {
return &protocol{ProtocolNumber4}
})
- stack.RegisterTransportProtocolFactory(ProtocolName6, func() stack.TransportProtocol {
- return &protocol{ProtocolNumber6}
- })
+ // TODO: Support IPv6.
}