コンテンツにスキップ

Appendix E Checksums

There are no built-in constructs in P416 for manipulating packet checksums. We expect that checksum operations can be expressed as extern library objects that are provided in target-specific libraries. The standard architecture library should provide such checksum units.

For example, one could provide an incremental checksum unit Checksum16 (also described in the VSS example in Section Available extern blocks) for computing 16-bit one’s complement using an extern object with a signature such as:

extern Checksum16 {
    Checksum16();              // constructor
    void clear();              // prepare unit for computation
    void update<T>(in T data); // add data to checksum
    void remove<T>(in T data); // remove data from existing checksum
    bit<16> get(); // get the checksum for the data added since last clear
}

IP checksum verification could be done in a parser as:

ck16.clear();           // prepare checksum unit
ck16.update(h.ipv4);    // write header
verify(ck16.get() == 16w0, error.IPv4ChecksumError); // check for 0 checksum

IP checksum generation could be done as:

h.ipv4.hdrChecksum = 16w0;
ck16.clear();
ck16.update(h.ipv4);
h.ipv4.hdrChecksum = ck16.get();

Moreover, some switch architectures do not perform checksum verification, but only update checksums incrementally to reflect packet modifications. This could be achieved as well, as the following P4 program fragments illustrates:

ck16.clear();
ck16.update(h.ipv4.hdrChecksum);  // original checksum
ck16.remove( { h.ipv4.ttl, h.ipv4.proto } );
h.ipv4.ttl = h.ipv4.ttl - 1;
ck16.update( { h.ipv4.ttl, h.ipv4.proto } );
h.ipv4.hdrChecksum = ck16.get();