Parse, Search, Modify, Queue.
Packet processing implies discrete receive events and the handling of these discrete receive events along with any requisite state collected prior to the events. What state is required will depend on the device. Example: a router only cares about configured ACLs and routing tables. The dynamicism is in configuration and routing protocols.
First, how does a packet come to a device? By configuration, the device is already aware of the layer 2 protocol. The frame from layer 2 must be examined for the packet's layer 3 protocol. On ethernet, there are three ways to do this:
- Ethertype
- LLC header
- SNAP header
Most courses pay only lipservice to this identification an quickly move on. But this identification is critical to understanding the ability to dual-stack, encapsulate in another protocol, etc. Being able to identify the upper-layer protocol is mandatory in all cases of parsing. If you're analyzing a protocol and cannot find a field to distinguish the upper-layer protocol, this information must be known through configuration.
Consider GRE tunnels. Most people would not call GRE a layer 2 protocol, but from a transport perspective, it could be seen as one. Now, lets say we're sending CLNS for IS-IS across GRE. By RFC2784, GRE protocol types are from Etherypes. But how does CLNS work? CLNS uses an LLC header! Clearly, there must be another mechanism. Is it even standardized? No. Reading the specification, only ethertypes from RFC1700 or from IANA suffice. But because the LLC header used 0xFE for the DSAP/SSAP and this isn't problematic to reuse (unlike in an actual Ethernet ethertype/length field, for which this would be interpreted as a length), it is simply accepted that this is what is done.
Another function of parsing can including determining whether the packet is even for us. In Ethernet, the destination MAC address either needs to be: 1) the MAC on the recipient interface, 2) a multicast MAC that the device accepts, or 3) the broadcast MAC. Some frame destined for another device doesn't need to be processed further.
The final goal for the parsing stage is to collect all of the relevant packet header data and make it accessible for the subsequent stages (particularly search stage).
So logical, so obvious, but it has meaning. In protocols like IPSec, fairly deep parsing is part of the game when deciding what key to use for encryption. Often times, I get into discussions on IPSec policy and, even among those that have recently worked with it and run into confusion over what all this configuration syntax is about. It is about determining which egress traffic needs to be encrypted, what the key should be, and what the outer tunnel header parameters are.
Search is a complex phase. Parsing is often implemented in one or two stages (usually preclassification and parsing), but search is often implemented in multiple stages (particularly in highly pipelined boxes). This is because there are many searches that have to be done. If the device is an ethernet switch, we need to search for the destination MAC _and_ the source MAC (for MAC learning purposes). In the case of an IP router, we may need to do ACL searches (for security ACL and policy routing, may be L4), NAT table searches, and, of course, destination IP search. In platforms that may look deeper for, say, intrusion detection/prevention, search phase may also find the buffers for reassembly and inspection of the stream.
Some protocols are directly implemented in network processors (e.g. BFD, CFM). For these cases, there is often a bypass of the usual functions. But what about protocols destined to the general purpose CPU (GPCPU)? These too must be identified. On some platforms, this involves an early search phase to avoid doing the regular lookup process. Again, this adds to the complexity of the search phase
Modify is a bit easier. Once the lookups have been completed, the processor has metadata available to perform the actual forwarding. If the device is an ethernet switch, nothing will be done, save for maybe VLAN imposition/disposition. For IP forwarding, the ethernet header must be rewritten, the TTL decremented, and the IP header checksum recalculated and rewritten. Things like NAT also have to be handled here as they result in a rewrite as well.
The queue stage is fairly hardware/code dependent in it's behavior and functionality. The queue stage may be sending to another port directly, to a fabric, or to the local CPU. Each of these paths usually has different queueing functionality owing to obvious differences in consumption.
What is the point of networking?
The perspective of networking that one chooses for analysis sets most of the path and history concerns.
We could think about things using a model of mail, telegraph, telephone, semaphores, maybe even smoke signals. Observing the modern network, the telegraph is a good way to consider the initial concept. In the later years of the telegraph's glory days, there was extensive automation and routing capabilities. Much like you would imagine from the telegraph's glory days, this automation was heavily mechanical moreso than electrical.
But the phone gives us another model, focusing on an end-to-end electrical connection. No minature messages or discrete switching times until digital switching. And even in digital switching, there was a dedicated path in some domain (whether time-domain, frequency-domain, spatial domain). The telephone network is state-heavy because each switch in between needs to know about each call traversing it. Or rather, all of this applies in pre-IP telephone networks (and to a different extent in post-IP)
In the old days, the goal was to send data for humans to consume. Well, we've moved beyond that in the most basic sense: most data sent across a network will not be directly consumed by a human, but will be aggregated, transformed, and otherwise put as part of some computational process. User interaction is only with the product of the computational process. The goals are not so simplistic to say that "I want to hear the other person" or "I want to watch a video". Instead, the goals are all of these, give me more, and something new.
The machines built around the network are forever computing, never judging, only executing. Firmly in control is code and hardware, written/designed through the best logic that it's inventors can come up with. Destabilizing control are the realities of the world, too numerous to even consider discrete, and too random for the inventor to forsee in totality. Working against the inventor's logic are people (hackers), events, and the resonance induced in time-space pulling away the functionality of the system.
So it is with the modern network. Machines, running code. Fragile machines. Pushing data for further crunching. Emotionlessly becoming useful to some end user.