Jedes eingehende Paket (PRE_ROUTING, für ausgehende Pakete ist der Vorgang analog) wird zunächst in eine ip_conntrack_tuple umgewandel und anschließend wird nach einer, schon bestehenden Verbindung, gesucht, die auf dieses Tupel passt. Ein solches Tupel enthält alle Merkmale einer Verbindung. Bei TCP sind das Quell- und Zieladresse und die jeweiligen Portnummern. Je nach Ergebnis der Suche wird das Paket mit einer der folgenden Konstanten bewertet:
Gehört das ankommende Paket einer schon bestehenden Verbindung an, so erhält man eine tuple_hash Struktur. Diese enthält zum einen das Tupel der Verbindung und zum anderen einen Zeiger auf eine ip_conntrack Struktur. Aufgrund der schon bestehenden Verbindung muss nur noch die Richtung des Pakets bestimmt werden. Für die Bewertung des Pakets ergeben sich nur die Möglichkeiten ESTABLISHED oder RELATED, falls es sich um ein erwartete Verbindung handelt, beide mit Angabe der Richtung.
Wurde keine bestehende Verbindung in der Hash-Tabelle gefunden, so muss zunächst eine neuen ip_conntrack Struktur angelegt werden. Hiezu werden zunächst die beiden tupel_hash (eine für jede Richtung) Strukturen erzeugt und das Protokol der Verbindung in die Struktur eingetragen. Anschließend muss überprüft werden ob es sich bei dieser Verbindung um eine bereits erwartete (expectation handelt.
Falls es eine bereits erwartete Verbindung ist, werden Master-Verbindung und die neue Verbindung verlinkt, und die Erwartung (expectation) wird, da sie nun erfüllt ist, ausgetragen. Um die Verbindung später als RELATED wieder zu erkennen, wird noch das EXPECTED-Bit gesetzt.
Erfüllt das Paket keine expectation, wird nach einem, auf dieses Tupel
passenden, registrierten Helper gesucht. Falls einer gefunden wurde, wird er ebenfalls in die ip_conntrack Struktur eingetragen. Fur ein Paket, dass eine neue Verbindung erzeugt, wird die Bewertung NEW vergeben.
Nachdem die Bewertung des Pakets feststeht, wird diese Information in den sk_buff eingetragen. Das Feld nfct der sk_buff Struktur enthält jetzt einen Zeiger auf das infos-Array des zugehörigen Conntrack. Mit Hilfe der Funktion ip_conntrack_get() erhält man aus dem nfct-Feld einmal die Bewertung des Pakets und auch einen Zeiger auf die zugehörige ip_conntrack Struktur. Diese Informationen werden später noch von NAT gebraucht.
Anschließend wird der Protokollabhängige Teil des Conntrack Codes ausgeführt. Es sind Funktionen für, die über IP liegenden Protokolle, UDP, TCP und ICMP implementiert. Hier wird, protokollabhängig, die Gültigkeit der Verbindung überprüft und eventuell noch Verbindungstimeouts aktualisiert. Bei TCP, zum Beispiel, wird, bei schon erhaltenem SYN Paket, auf ein entsprechendes ACK gewartet. Erst nach eingegangenem ACK wird der Verbindungsstatus auf ,,ASSURED`` gesetzt. Verbindungen die nicht als ,,ASSURDED`` klassifiziert sind, werden, falls die Hash-Tabelle voll ist, zuerst entfernt.
Zuletzt wird, sofern ein Helper für diese Verbindung gefunden wurde, die entsprechende help() Funktion aufgerufen. (Vgl. Conntrack Helper / Nat Helper)
Verbindungen werden erst dann in die Hash-Tabelle eingetragen, wenn sie bestätigt wurden, d.h. Conntrack wartet mit dem Eintrag in die Hashtabelle, bis das Paket die Netfilter Hooks NF_IP_LOCAL_IN oder NF_IP_POST_ROUTING passiert hat. In diesem Fall kann man sicher sein, dass die Verbindung nicht durch eine Firewall Regel verworfen wurde.
Jede Verbindung wird zweimal in die Tabelle eingetragen, und zwar einmal für jede Richtung. Das heißt es werden zwei tuple_hash Strukturen, die jeweils auf den gleichen Conntrack verweisen, eingetragen.
struct ip_conntrack_tupel:
struct ip_conntrack:
Auch lässt sich das Connection Tracking flexibel erweitern durch: