next up previous
Next: 2.2.1 Comments upon problems/limitations Up: 2 Current KLIPS input/output Previous: 2.1.1 Comments upon problems/limitations

2.2 input: ipsec_rcv

  1. increment module use count
  2. verify skb and data is not NULL
  3. verify hard header length
  4. clone (COW) if necessary
  5. a number of poorly documented ``assertions''
  6. verify protocol number against packet and against protocol structure
  7. verify that protocol is AH, COMP or ESP.
  8. lookup each ipsecX device to determine which one has been bound to the receiving device. Grab ipsecprv device info.
  9. if no device found, warn, but do not die
  10. begin decap loop
    1. lock tdb if this is first time through
    2. verify that length is appropriate multiple if ESP
    3. switch on protocol type, grab SPI value from appropriate place
    4. format sa with satoa. (not found in code)
    5. if AH, then determine AH header length, find next protocol value, and verify against expected length of AH header.
    6. get spin lock if required
    7. if IPCOMP
      1. check if IPCOMP is out most header, (not yet supported)
      2. advance the tdb pointer and, if doing inbound policy check, then check SPI value. Complain if not matched.
      3. decompress packet, reset ip header pointer to new value, loop (via continue)
    8. lookup tdb based upon SA. gettdb
    9. complain if no tdb
    10. if doing inbound policy check
      1. check that outer source matches one on packet.
      2. check that this tdb is the expected next from previous. (forward check)
      3. check that this tdb expects to be attached to previous. (reverse check)
    11. check if tdb state is larval, skip
    12. check if tdb state is dead, complain
    13. check lifetime (bytes - soft/hard, addtime - soft/hard, usetime - soft/hard, packet count - soft/hard). Expire TDB, tell pfkey if limit exceeded.
    14. pick authlen, switch on auth type (MD5, SHA1)
    15. switch on protocol type (ESP, AH only) and set up authenticator
    16. check sequence number to see if replay window rolled, if so expire
    17. check out replay window, dropping if it is a replay
    18. verify authenticator, check if there was authentication, switch on type
      1. MD5, call MD5Update and friends, checking if ESP or AH was involved
      2. SHA1, call SHA1Update and friends, checking if ESP or AH was involved
      3. none, do nothing
    19. check authenticator for NULL (which would imply not AH or ESP above)
    20. compare authenticator against hash, complain if failed
    21. update the replay window
    22. switch on protocol type
      1. if ESP
        1. switch on encryption algorithm
          • if 3DES, then find IV and set header length
          • otherwise, fail
        2. locate ciphertext based upon header length
        3. switch on encryption algorithm
          • if 3DES, verify data length multiple of 8 and decrypt.
          • no otherwise clause
        4. find next header type
        5. find padding
        6. verify padding
      2. if AH, do nothing
    23. update protocol number in header (why?)
    24. switch on protocol type
      1. if ESP, the memmove as appropriate for ESP, skb_pull() to compact, and then skb_trim.
      2. if AH, then memmove as appropriate for AH, skb_pull().
    25. update skb pointers to parts of packet.
    26. nuke any options that skb knew about, or skb->proto_priv (2.2+)
    1. recalculate the header checksum
    2. set the sbk protocol type to IP over ethernet
    3. advance tdb pointers
    4. if doing inbound policy check
      1. verify that backward policy agrees with forward policy
      2. check if next protocol field is not one we know about
        1. complain that policy was not complete
    5. update ipcomp ratio counters if IPCOMP was involved, but this stage is not IPCOMP
    6. update the lifetime values in bytes, packets, and last used time.
    7. loop again if ESP, AH or IPCOMP

  11. if original chain was IPCOMP, then advance tdb chain once (Why?)
  12. if there is one last tdb
    1. verify that last protocol type was IPIP (no transport supported here)
    2. if doing inbound policy checks
      1. advance tdbnext with inext, and complain if non-NULL. (i.e. check that this was last tdb)
      2. verify source IP address matches tdb source
    3. update lifetimes for this tdb
    4. if skb data len is too small for header length, complain
    5. pull up new header into skb
    6. advance ip pointer to inner header
    7. update raw header pointer
    8. zero protocol options
    9. update layer 2 protocol info to IP over Ethernet
    10. reset checksum info
  13. if we are doing EROUTE checking (i.e. tunnel exit checking)
    1. setup for look up by src/dst in eroute table, checking for IPIP header.
    2. lock eroute table, lookup eroute
    3. record info we need and unlock
    4. if we found what we need, then lock, and lookup policy information by new said block.
    5. if no tdb found, then we drop packet
    6. walk policy_tdb chain, look for last one
    7. compare against tdb that we just used, complain if not the same.
  14. unlock tbd
  15. update stats if appropriate
  16. release packet destination
  17. if there was a layer 2, copy it back into place
  18. do inbound policy checks if it was IPCOMP
  19. do connection tracking
  20. drop packet back into bottom half queue

next up previous
Next: 2.2.1 Comments upon problems/limitations Up: 2 Current KLIPS input/output Previous: 2.1.1 Comments upon problems/limitations
Michael Richardson