summaryrefslogtreecommitdiffhomepage
path: root/pkg/tcpip/network/ipv4
diff options
context:
space:
mode:
authorGhanan Gowripalan <ghanan@google.com>2020-07-30 14:19:38 -0700
committergVisor bot <gvisor-bot@google.com>2020-07-30 14:25:53 -0700
commit9960a816a9ad65a4a6620eee5a66e5cc071b60cb (patch)
treea11f84b9a16e60d3038e77ca8bb215cd54841653 /pkg/tcpip/network/ipv4
parent3c70b4c986a2a6bb9b26f96e88f7fee878f29326 (diff)
Enforce fragment block size and validate args
Allow configuring fragmentation.Fragmentation with a fragment block size which will be enforced when processing fragments. Also validate arguments when processing fragments. Test: - fragmentation.TestErrors - ipv6_test.TestReceiveIPv6Fragments - ipv4_test.TestReceiveIPv6Fragments PiperOrigin-RevId: 324081521
Diffstat (limited to 'pkg/tcpip/network/ipv4')
-rw-r--r--pkg/tcpip/network/ipv4/ipv4.go6
-rw-r--r--pkg/tcpip/network/ipv4/ipv4_test.go53
2 files changed, 58 insertions, 1 deletions
diff --git a/pkg/tcpip/network/ipv4/ipv4.go b/pkg/tcpip/network/ipv4/ipv4.go
index b1776e5ee..0b5a35cce 100644
--- a/pkg/tcpip/network/ipv4/ipv4.go
+++ b/pkg/tcpip/network/ipv4/ipv4.go
@@ -45,6 +45,10 @@ const (
// buckets is the number of identifier buckets.
buckets = 2048
+
+ // The size of a fragment block, in bytes, as per RFC 791 section 3.1,
+ // page 14.
+ fragmentblockSize = 8
)
type endpoint struct {
@@ -66,7 +70,7 @@ func (p *protocol) NewEndpoint(nicID tcpip.NICID, addrWithPrefix tcpip.AddressWi
prefixLen: addrWithPrefix.PrefixLen,
linkEP: linkEP,
dispatcher: dispatcher,
- fragmentation: fragmentation.NewFragmentation(fragmentation.HighFragThreshold, fragmentation.LowFragThreshold, fragmentation.DefaultReassembleTimeout),
+ fragmentation: fragmentation.NewFragmentation(fragmentblockSize, fragmentation.HighFragThreshold, fragmentation.LowFragThreshold, fragmentation.DefaultReassembleTimeout),
protocol: p,
stack: st,
}
diff --git a/pkg/tcpip/network/ipv4/ipv4_test.go b/pkg/tcpip/network/ipv4/ipv4_test.go
index 11e579c4b..4f82c45e2 100644
--- a/pkg/tcpip/network/ipv4/ipv4_test.go
+++ b/pkg/tcpip/network/ipv4/ipv4_test.go
@@ -519,6 +519,11 @@ func TestReceiveFragments(t *testing.T) {
// UDP header plus a payload of 0..256 in increments of 2.
ipv4Payload2 := udpGen(128, 2)
udpPayload2 := ipv4Payload2[header.UDPMinimumSize:]
+ // UDP header plus a payload of 0..256 in increments of 3.
+ // Used to test cases where the fragment blocks are not a multiple of
+ // the fragment block size of 8 (RFC 791 section 3.1 page 14).
+ ipv4Payload3 := udpGen(127, 3)
+ udpPayload3 := ipv4Payload3[header.UDPMinimumSize:]
type fragmentData struct {
id uint16
@@ -545,6 +550,18 @@ func TestReceiveFragments(t *testing.T) {
expectedPayloads: [][]byte{udpPayload1},
},
{
+ name: "No fragmentation with size not a multiple of fragment block size",
+ fragments: []fragmentData{
+ {
+ id: 1,
+ flags: 0,
+ fragmentOffset: 0,
+ payload: ipv4Payload3,
+ },
+ },
+ expectedPayloads: [][]byte{udpPayload3},
+ },
+ {
name: "More fragments without payload",
fragments: []fragmentData{
{
@@ -587,6 +604,42 @@ func TestReceiveFragments(t *testing.T) {
expectedPayloads: [][]byte{udpPayload1},
},
{
+ name: "Two fragments with last fragment size not a multiple of fragment block size",
+ fragments: []fragmentData{
+ {
+ id: 1,
+ flags: header.IPv4FlagMoreFragments,
+ fragmentOffset: 0,
+ payload: ipv4Payload3[:64],
+ },
+ {
+ id: 1,
+ flags: 0,
+ fragmentOffset: 64,
+ payload: ipv4Payload3[64:],
+ },
+ },
+ expectedPayloads: [][]byte{udpPayload3},
+ },
+ {
+ name: "Two fragments with first fragment size not a multiple of fragment block size",
+ fragments: []fragmentData{
+ {
+ id: 1,
+ flags: header.IPv4FlagMoreFragments,
+ fragmentOffset: 0,
+ payload: ipv4Payload3[:63],
+ },
+ {
+ id: 1,
+ flags: 0,
+ fragmentOffset: 63,
+ payload: ipv4Payload3[63:],
+ },
+ },
+ expectedPayloads: nil,
+ },
+ {
name: "Second fragment has MoreFlags set",
fragments: []fragmentData{
{