summaryrefslogtreecommitdiffhomepage
path: root/pkg/tcpip/network/ipv6/ipv6.go
diff options
context:
space:
mode:
authorGhanan Gowripalan <ghanan@google.com>2020-11-13 13:10:51 -0800
committergVisor bot <gvisor-bot@google.com>2020-11-13 13:13:21 -0800
commit6c0f53002a7f3a518befbe667d308c3d64cc9a59 (patch)
tree50119065f7d1e050034d7c875ef5816d19b20903 /pkg/tcpip/network/ipv6/ipv6.go
parentd5e17d2dbc2809c6d70153f0d4c996eff899e69d (diff)
Decrement TTL/Hop Limit when forwarding IP packets
If the packet must no longer be forwarded because its TTL/Hop Limit reaches 0, send an ICMP Time Exceeded error to the source. Required as per relevant RFCs. See comments in code for RFC references. Fixes #1085 Tests: - ipv4_test.TestForwarding - ipv6.TestForwarding PiperOrigin-RevId: 342323610
Diffstat (limited to 'pkg/tcpip/network/ipv6/ipv6.go')
-rw-r--r--pkg/tcpip/network/ipv6/ipv6.go29
1 files changed, 24 insertions, 5 deletions
diff --git a/pkg/tcpip/network/ipv6/ipv6.go b/pkg/tcpip/network/ipv6/ipv6.go
index 38a0633bd..7697ff987 100644
--- a/pkg/tcpip/network/ipv6/ipv6.go
+++ b/pkg/tcpip/network/ipv6/ipv6.go
@@ -645,6 +645,18 @@ func (e *endpoint) WriteHeaderIncludedPacket(r *stack.Route, pkt *stack.PacketBu
// forwardPacket attempts to forward a packet to its final destination.
func (e *endpoint) forwardPacket(pkt *stack.PacketBuffer) *tcpip.Error {
h := header.IPv6(pkt.NetworkHeader().View())
+ hopLimit := h.HopLimit()
+ if hopLimit <= 1 {
+ // As per RFC 4443 section 3.3,
+ //
+ // If a router receives a packet with a Hop Limit of zero, or if a
+ // router decrements a packet's Hop Limit to zero, it MUST discard the
+ // packet and originate an ICMPv6 Time Exceeded message with Code 0 to
+ // the source of the packet. This indicates either a routing loop or
+ // too small an initial Hop Limit value.
+ return e.protocol.returnError(&icmpReasonHopLimitExceeded{}, pkt)
+ }
+
dstAddr := h.DestinationAddress()
// Check if the destination is owned by the stack.
@@ -663,13 +675,20 @@ func (e *endpoint) forwardPacket(pkt *stack.PacketBuffer) *tcpip.Error {
}
defer r.Release()
- // TODO(b/143425874) Decrease the TTL field in forwarded packets.
+ // We need to do a deep copy of the IP packet because
+ // WriteHeaderIncludedPacket takes ownership of the packet buffer, but we do
+ // not own it.
+ newHdr := header.IPv6(stack.PayloadSince(pkt.NetworkHeader()))
+
+ // As per RFC 8200 section 3,
+ //
+ // Hop Limit 8-bit unsigned integer. Decremented by 1 by
+ // each node that forwards the packet.
+ newHdr.SetHopLimit(hopLimit - 1)
+
return r.WriteHeaderIncludedPacket(stack.NewPacketBuffer(stack.PacketBufferOptions{
ReserveHeaderBytes: int(r.MaxHeaderLength()),
- // We need to do a deep copy of the IP packet because
- // WriteHeaderIncludedPacket takes ownership of the packet buffer, but we do
- // not own it.
- Data: stack.PayloadSince(pkt.NetworkHeader()).ToVectorisedView(),
+ Data: buffer.View(newHdr).ToVectorisedView(),
}))
}