summaryrefslogtreecommitdiffhomepage
path: root/pkg/tcpip/network
diff options
context:
space:
mode:
authorBert Muthalaly <stijlist@google.com>2018-09-05 17:33:18 -0700
committerShentubot <shentubot@google.com>2018-09-05 17:34:25 -0700
commit5685d6b5add2acce9618aa908b846f5ce3658346 (patch)
treeca93fb55c83ebf77806957c73c3951fc01844560 /pkg/tcpip/network
parentfe8ca76c22ff03c9ae8bf524031553d65b30f53d (diff)
Update {LinkEndpoint,NetworkEndpoint}#WritePacket to take a VectorisedView
Makes it possible to avoid copying or allocating in cases where DeliverNetworkPacket (rx) needs to turn around and call WritePacket (tx) with its VectorisedView. Also removes the restriction on having VectorisedViews with multiple views in the write path. PiperOrigin-RevId: 211728717 Change-Id: Ie03a65ecb4e28bd15ebdb9c69f05eced18fdfcff
Diffstat (limited to 'pkg/tcpip/network')
-rw-r--r--pkg/tcpip/network/arp/arp.go6
-rw-r--r--pkg/tcpip/network/ip_test.go18
-rw-r--r--pkg/tcpip/network/ipv4/icmp.go3
-rw-r--r--pkg/tcpip/network/ipv4/ipv4.go4
-rw-r--r--pkg/tcpip/network/ipv6/icmp.go22
-rw-r--r--pkg/tcpip/network/ipv6/icmp_test.go2
-rw-r--r--pkg/tcpip/network/ipv6/ipv6.go7
7 files changed, 31 insertions, 31 deletions
diff --git a/pkg/tcpip/network/arp/arp.go b/pkg/tcpip/network/arp/arp.go
index e7dfc6444..6bf4be868 100644
--- a/pkg/tcpip/network/arp/arp.go
+++ b/pkg/tcpip/network/arp/arp.go
@@ -74,7 +74,7 @@ func (e *endpoint) MaxHeaderLength() uint16 {
func (e *endpoint) Close() {}
-func (e *endpoint) WritePacket(r *stack.Route, hdr *buffer.Prependable, payload buffer.View, protocol tcpip.TransportProtocolNumber) *tcpip.Error {
+func (e *endpoint) WritePacket(r *stack.Route, hdr *buffer.Prependable, payload buffer.VectorisedView, protocol tcpip.TransportProtocolNumber) *tcpip.Error {
return tcpip.ErrNotSupported
}
@@ -98,7 +98,7 @@ func (e *endpoint) HandlePacket(r *stack.Route, vv *buffer.VectorisedView) {
copy(pkt.HardwareAddressSender(), r.LocalLinkAddress[:])
copy(pkt.ProtocolAddressSender(), h.ProtocolAddressTarget())
copy(pkt.ProtocolAddressTarget(), h.ProtocolAddressSender())
- e.linkEP.WritePacket(r, &hdr, nil, ProtocolNumber)
+ e.linkEP.WritePacket(r, &hdr, buffer.VectorisedView{}, ProtocolNumber)
fallthrough // also fill the cache from requests
case header.ARPReply:
addr := tcpip.Address(h.ProtocolAddressSender())
@@ -150,7 +150,7 @@ func (*protocol) LinkAddressRequest(addr, localAddr tcpip.Address, linkEP stack.
copy(h.ProtocolAddressSender(), localAddr)
copy(h.ProtocolAddressTarget(), addr)
- return linkEP.WritePacket(r, &hdr, nil, ProtocolNumber)
+ return linkEP.WritePacket(r, &hdr, buffer.VectorisedView{}, ProtocolNumber)
}
// ResolveStaticAddress implements stack.LinkAddressResolver.
diff --git a/pkg/tcpip/network/ip_test.go b/pkg/tcpip/network/ip_test.go
index 4475a75cf..1e92b7ae9 100644
--- a/pkg/tcpip/network/ip_test.go
+++ b/pkg/tcpip/network/ip_test.go
@@ -66,7 +66,7 @@ type testObject struct {
// checkValues verifies that the transport protocol, data contents, src & dst
// addresses of a packet match what's expected. If any field doesn't match, the
// test fails.
-func (t *testObject) checkValues(protocol tcpip.TransportProtocolNumber, vv *buffer.VectorisedView, srcAddr, dstAddr tcpip.Address) {
+func (t *testObject) checkValues(protocol tcpip.TransportProtocolNumber, vv buffer.VectorisedView, srcAddr, dstAddr tcpip.Address) {
v := vv.ToView()
if protocol != t.protocol {
t.t.Errorf("protocol = %v, want %v", protocol, t.protocol)
@@ -95,7 +95,7 @@ func (t *testObject) checkValues(protocol tcpip.TransportProtocolNumber, vv *buf
// packets. This is used by the test object to verify that the results of the
// parsing are expected.
func (t *testObject) DeliverTransportPacket(r *stack.Route, protocol tcpip.TransportProtocolNumber, vv *buffer.VectorisedView) {
- t.checkValues(protocol, vv, r.RemoteAddress, r.LocalAddress)
+ t.checkValues(protocol, *vv, r.RemoteAddress, r.LocalAddress)
t.dataCalls++
}
@@ -103,7 +103,7 @@ func (t *testObject) DeliverTransportPacket(r *stack.Route, protocol tcpip.Trans
// incoming control (ICMP) packets. This is used by the test object to verify
// that the results of the parsing are expected.
func (t *testObject) DeliverTransportControlPacket(local, remote tcpip.Address, net tcpip.NetworkProtocolNumber, trans tcpip.TransportProtocolNumber, typ stack.ControlType, extra uint32, vv *buffer.VectorisedView) {
- t.checkValues(trans, vv, remote, local)
+ t.checkValues(trans, *vv, remote, local)
if typ != t.typ {
t.t.Errorf("typ = %v, want %v", typ, t.typ)
}
@@ -145,7 +145,7 @@ func (*testObject) LinkAddress() tcpip.LinkAddress {
// WritePacket is called by network endpoints after producing a packet and
// writing it to the link endpoint. This is used by the test object to verify
// that the produced packet is as expected.
-func (t *testObject) WritePacket(_ *stack.Route, hdr *buffer.Prependable, payload buffer.View, protocol tcpip.NetworkProtocolNumber) *tcpip.Error {
+func (t *testObject) WritePacket(_ *stack.Route, hdr *buffer.Prependable, payload buffer.VectorisedView, protocol tcpip.NetworkProtocolNumber) *tcpip.Error {
var prot tcpip.TransportProtocolNumber
var srcAddr tcpip.Address
var dstAddr tcpip.Address
@@ -162,9 +162,7 @@ func (t *testObject) WritePacket(_ *stack.Route, hdr *buffer.Prependable, payloa
srcAddr = h.SourceAddress()
dstAddr = h.DestinationAddress()
}
- var views [1]buffer.View
- vv := payload.ToVectorisedView(views)
- t.checkValues(prot, &vv, srcAddr, dstAddr)
+ t.checkValues(prot, payload, srcAddr, dstAddr)
return nil
}
@@ -223,7 +221,8 @@ func TestIPv4Send(t *testing.T) {
if err != nil {
t.Fatalf("could not find route: %v", err)
}
- if err := ep.WritePacket(&r, &hdr, payload, 123); err != nil {
+ vv := buffer.NewVectorisedView(len(payload), []buffer.View{payload})
+ if err := ep.WritePacket(&r, &hdr, vv, 123); err != nil {
t.Fatalf("WritePacket failed: %v", err)
}
}
@@ -461,7 +460,8 @@ func TestIPv6Send(t *testing.T) {
if err != nil {
t.Fatalf("could not find route: %v", err)
}
- if err := ep.WritePacket(&r, &hdr, payload, 123); err != nil {
+ vv := buffer.NewVectorisedView(len(payload), []buffer.View{payload})
+ if err := ep.WritePacket(&r, &hdr, vv, 123); err != nil {
t.Fatalf("WritePacket failed: %v", err)
}
}
diff --git a/pkg/tcpip/network/ipv4/icmp.go b/pkg/tcpip/network/ipv4/icmp.go
index d11938d6e..de21e623e 100644
--- a/pkg/tcpip/network/ipv4/icmp.go
+++ b/pkg/tcpip/network/ipv4/icmp.go
@@ -120,5 +120,6 @@ func sendPing4(r *stack.Route, code byte, data buffer.View) *tcpip.Error {
data = data[header.ICMPv4EchoMinimumSize-header.ICMPv4MinimumSize:]
icmpv4.SetChecksum(^header.Checksum(icmpv4, header.Checksum(data, 0)))
- return r.WritePacket(&hdr, data, header.ICMPv4ProtocolNumber)
+ vv := buffer.NewVectorisedView(len(data), []buffer.View{data})
+ return r.WritePacket(&hdr, vv, header.ICMPv4ProtocolNumber)
}
diff --git a/pkg/tcpip/network/ipv4/ipv4.go b/pkg/tcpip/network/ipv4/ipv4.go
index 143d8e73e..478957827 100644
--- a/pkg/tcpip/network/ipv4/ipv4.go
+++ b/pkg/tcpip/network/ipv4/ipv4.go
@@ -106,9 +106,9 @@ func (e *endpoint) MaxHeaderLength() uint16 {
}
// WritePacket writes a packet to the given destination address and protocol.
-func (e *endpoint) WritePacket(r *stack.Route, hdr *buffer.Prependable, payload buffer.View, protocol tcpip.TransportProtocolNumber) *tcpip.Error {
+func (e *endpoint) WritePacket(r *stack.Route, hdr *buffer.Prependable, payload buffer.VectorisedView, protocol tcpip.TransportProtocolNumber) *tcpip.Error {
ip := header.IPv4(hdr.Prepend(header.IPv4MinimumSize))
- length := uint16(hdr.UsedLength() + len(payload))
+ length := uint16(hdr.UsedLength() + payload.Size())
id := uint32(0)
if length > header.IPv4MaximumHeaderSize+8 {
// Packets of 68 bytes or less are required by RFC 791 to not be
diff --git a/pkg/tcpip/network/ipv6/icmp.go b/pkg/tcpip/network/ipv6/icmp.go
index e3ef89d26..b18b78830 100644
--- a/pkg/tcpip/network/ipv6/icmp.go
+++ b/pkg/tcpip/network/ipv6/icmp.go
@@ -62,6 +62,7 @@ func (e *endpoint) handleControl(typ stack.ControlType, extra uint32, vv *buffer
e.dispatcher.DeliverTransportControlPacket(e.id.LocalAddress, h.DestinationAddress(), ProtocolNumber, p, typ, extra, vv)
}
+// TODO: take buffer.VectorisedView by value.
func (e *endpoint) handleICMP(r *stack.Route, vv *buffer.VectorisedView) {
v := vv.First()
if len(v) < header.ICMPv6MinimumSize {
@@ -105,8 +106,8 @@ func (e *endpoint) handleICMP(r *stack.Route, vv *buffer.VectorisedView) {
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)
+ pkt.SetChecksum(icmpChecksum(pkt, r.LocalAddress, r.RemoteAddress, buffer.VectorisedView{}))
+ r.WritePacket(&hdr, buffer.VectorisedView{}, header.ICMPv6ProtocolNumber)
e.linkAddrCache.AddLinkAddress(e.nicid, r.RemoteAddress, r.RemoteLinkAddress)
@@ -125,13 +126,12 @@ func (e *endpoint) handleICMP(r *stack.Route, vv *buffer.VectorisedView) {
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)
+ pkt.SetChecksum(icmpChecksum(pkt, r.LocalAddress, r.RemoteAddress, *vv))
+ r.WritePacket(&hdr, *vv, header.ICMPv6ProtocolNumber)
case header.ICMPv6EchoReply:
if len(v) < header.ICMPv6EchoMinimumSize {
@@ -185,7 +185,7 @@ func (*protocol) LinkAddressRequest(addr, localAddr tcpip.Address, linkEP stack.
pkt[icmpV6OptOffset] = ndpOptSrcLinkAddr
pkt[icmpV6LengthOffset] = 1
copy(pkt[icmpV6LengthOffset+1:], linkEP.LinkAddress())
- pkt.SetChecksum(icmpChecksum(pkt, r.LocalAddress, r.RemoteAddress, nil))
+ pkt.SetChecksum(icmpChecksum(pkt, r.LocalAddress, r.RemoteAddress, buffer.VectorisedView{}))
length := uint16(hdr.UsedLength())
ip := header.IPv6(hdr.Prepend(header.IPv6MinimumSize))
@@ -197,7 +197,7 @@ func (*protocol) LinkAddressRequest(addr, localAddr tcpip.Address, linkEP stack.
DstAddr: r.RemoteAddress,
})
- return linkEP.WritePacket(r, &hdr, nil, ProtocolNumber)
+ return linkEP.WritePacket(r, &hdr, buffer.VectorisedView{}, ProtocolNumber)
}
// ResolveStaticAddress implements stack.LinkAddressResolver.
@@ -205,15 +205,17 @@ func (*protocol) ResolveStaticAddress(addr tcpip.Address) (tcpip.LinkAddress, bo
return "", false
}
-func icmpChecksum(h header.ICMPv6, src, dst tcpip.Address, data []byte) uint16 {
+func icmpChecksum(h header.ICMPv6, src, dst tcpip.Address, vv buffer.VectorisedView) 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)))
+ binary.BigEndian.PutUint32(upperLayerLength[:], uint32(len(h)+vv.Size()))
xsum = header.Checksum(upperLayerLength[:], xsum)
xsum = header.Checksum([]byte{0, 0, 0, uint8(header.ICMPv6ProtocolNumber)}, xsum)
- xsum = header.Checksum(data, xsum)
+ for _, v := range vv.Views() {
+ xsum = header.Checksum(v, xsum)
+ }
// h[2:4] is the checksum itself, set it aside to avoid checksumming the checksum.
h2, h3 := h[2], h[3]
diff --git a/pkg/tcpip/network/ipv6/icmp_test.go b/pkg/tcpip/network/ipv6/icmp_test.go
index 582bbb40e..e9f400fe4 100644
--- a/pkg/tcpip/network/ipv6/icmp_test.go
+++ b/pkg/tcpip/network/ipv6/icmp_test.go
@@ -186,7 +186,7 @@ func TestLinkResolution(t *testing.T) {
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))
+ pkt.SetChecksum(icmpChecksum(pkt, r.LocalAddress, r.RemoteAddress, buffer.VectorisedView{}))
payload := tcpip.SlicePayload(hdr.UsedBytes())
// We can't send our payload directly over the route because that
diff --git a/pkg/tcpip/network/ipv6/ipv6.go b/pkg/tcpip/network/ipv6/ipv6.go
index cdb8284a2..19dc1b49e 100644
--- a/pkg/tcpip/network/ipv6/ipv6.go
+++ b/pkg/tcpip/network/ipv6/ipv6.go
@@ -82,11 +82,8 @@ func (e *endpoint) MaxHeaderLength() uint16 {
}
// WritePacket writes a packet to the given destination address and protocol.
-func (e *endpoint) WritePacket(r *stack.Route, hdr *buffer.Prependable, payload buffer.View, protocol tcpip.TransportProtocolNumber) *tcpip.Error {
- length := uint16(hdr.UsedLength())
- if payload != nil {
- length += uint16(len(payload))
- }
+func (e *endpoint) WritePacket(r *stack.Route, hdr *buffer.Prependable, payload buffer.VectorisedView, protocol tcpip.TransportProtocolNumber) *tcpip.Error {
+ length := uint16(hdr.UsedLength() + payload.Size())
ip := header.IPv6(hdr.Prepend(header.IPv6MinimumSize))
ip.Encode(&header.IPv6Fields{
PayloadLength: length,