# Graybox Tests: pktgen

The pktgen tests are the first group of packets Graybox was tasked with checking. Their purpose and rationale was more or less lost to time, and this document is a very late attempt to rediscover and document them.

They are seemingly named after the [Packet Generator](https://github.com/ydahhrk/PktGenerator) (PG). This is a bit strange since the latter was always meant as Graybox's official packet source, not just the first ones. (Consider renaming "pktgen" to "auto" or something.)

They were born in February 2015 at the latest, using a very early version of the PG (probably [this one](https://github.com/ydahhrk/PktGenerator/blob/2e9954fb4640afffe5b7d08e57918f1f91250321/src/mx/nic/jool/pktgen/auto/PacketGenAuto.java), which had no input and simply spew them in batch). They were meant to test whatever I was developing at the time, rather than specific RFC requirements.

The test designer appears to have been concerned with the variables explained in the subsections below. The batch generated all possible combinations of these variables across all supported protocols.

## Checksum correctness (`csumok` vs `csumfail`)

These variants are meant to check that a correct layer 4 checksum (L4C) translates into a correct L4C, and an incorrect L4C translates into an "equivalent" incorrect L4C instead of a packet drop (for performance reasons). This applies to TCP, UDP and ICMP informationals. (ICMP errors do require checksum validation because the additional internal header translation, possible packet truncation and ICMP Extension modifications essentially require it to be recomputed from scratch.)

None of these tests mess with the IPv4 header checksum (IHC). (Incorrect IHC triggers drop by Linux before the packet even reaches Jool, and IHC itself does not translate anyway.)

I don't particularly care for `csumok`, but incorrect checksum translation is not hammered by any posterior tests and as such are still valuable.

## Atomic fragments (`df-nofrag` vs `nodf-nofrag`)

(`df` in an IPv4 packet means "DF enabled," `nodf` means "DF disabled." In an IPv6 packet, `df` means "excludes fragment header," `nodf` means "includes fragment header." Before [Atomic Fragment Deprecation](https://tools.ietf.org/html/rfc8021) (AFD), the presence of the fragment header used to be an IPv6 counterpart of DF.)

The pktgen tests predate AFD, so it is strange to me that they do not appear to have required modifications in the meantime. Perhaps there is more to this variant that escapes me.

As far as I know, the variant is presently only valuable in that it ensures Jool does something sensible when atomic fragments do show up.

I had to modify the NAT64 6-to-4 `nodf-nofrag` tests in 2020-05-14 to account for Graybox's identification/checksum verification improvements. Because `defrag` deletes the fragment header on atomic fragments, identification cannot survive the translation. We choose to live with this because I don't see how to fix it and atomic fragments are useless anyway. So, when translating IPv6 identification 0x87654321, the new versions of the packets expect zero (which, in identification's case, means "whatever") instead of 0x4321.

These new packets were generated by changing [this](https://github.com/ydahhrk/PktGenerator/blob/2e9954fb4640afffe5b7d08e57918f1f91250321/src/mx/nic/jool/pktgen/auto/BasicTests.java#L233) into `final int idB = 0x0;`.

This hadn't affected us before because of the `NOFRAG_IGNORE` hack.

## Fragmentation (`nodf-frag<n>`)

I think this stems from the following requirement from RFC 7915:

> The translator SHOULD make sure that the packets belonging to the
> same flow leave the translator in the same order in which they
> arrived.

Particularly since IPv6 forwarders are not supposed to mess with fragmentation, I have always wondered if the above implies the following or not:

> The translator SHOULD NOT move layer 3 payload from one fragment to another.

For example, is the translator allowed to move the head of the second fragment's payload into the tail of the first? Would this count as changing the "order"? (Particularly since, if you move the entire contents of a fragment, it ceases to exist. Third becomes second. Out of order.)

(It probably doesn't matter. I've heard that Windows used to drop fragments arriving out of order at some point, and the requirement was probably inspired by that.)

So the idea is, the `frag<n>` tests send three fragments, and ensure they preserve payload after translation.

I had to comment out the NAT64 version of these tests on 2018-10-10 because `enfrag` fragments `defrag`-queued packets based on nexthop MTU instead of allocated size. I don't know if this can be fixed, but it probably doesn't matter because `defrag` already inevitably rearranges fragments during reassembly to begin with.

So, even if I weren't taking the requirement with a grain of salt, I don't think it can be satisfied in the NAT64 realm, in the Linux environment.

Because of this, I'm not entirely sure if there's value in preserving the `frag<n>` tests.
