Note this is not a duplicate of Why is the IP layer aware of higher layers in the network stack?
The need for a protocol identifier (eg. the IP header's Protocol field) in packet-based communication is clear: It's either this or some sort of computationally-intensive inference algorithm. The question is: why must it exist as part of the IP header rather than in the encapsulated protocols' headers?
It seems to me that this one of those cases where theoretical clarity meets practical considerations (AKA "Haskell meets Go"...): On the one hand placing a "protocol" field in the IP header breaks the conceptual separation of interests that eg. the OSI model aimed for; on the other hand forcing protocols higher up the stack to state their type in a consistent manner is much harder, and would eventually lead to a similar situation anyway (eg. if every protocol higher up the stack used its first header byte to state its type, it would look as if IP used its last header byte to do the same).
So my question is - what was the reasoning behind placing the "protocol" field inside the IP's packet header rather than anywhere else?
Edit: When writing this question I pondered whether to add the word "original" before "reasoning", ie the reasoning of the team that devised IP, but reckoned it was redundant as the question was phrased in the past tense ("what was the reasoning..."). Nevertheless this seems needed, as none of the replies actually answers that question. Some insights of note:
- @immibis suggests any other form would break other protocols' models (eg. encrypted communication protocols would have to have a plaintext identification field)
- @Eddie essentially states that the reason is convention (acceptance of the protocol chain design, though why that's the convention remains a mystery)
- @Ricky stresses practicality as an overarching consideration
- @Claudio suggests that were the protocol field a part of the encapsulated header there would be need for an additional header identification step, where in the current model that takes place during the IP header's parsing
So I'll rephrase: What's wrong with a model where instead of every header identifying the next header's type, every header identifies its own type in a predetermined location (eg. in the first header byte)? Why is such a model any less desirable than the current one?
Edit #2: It seems that the answer is a combination of several of the answers given (mainly those mentioned above along with @Eddie's second addendum):
Simplicity: Breaking the principal of layer agnosticism in this particular case means the stack (or the model) as a whole can be simpler:
- There's no "protocol identification" phase, neither implicit nor explicit
- Layer independence is improved (eg. an encrypted communications handler doesn't have to share a layer with any helper protocol)
Regulation is also greatly simplified, not having to enforce any requirements on client protocols.
Performance: Stating the protocol of an encapsulated packet ahead of the packet itself allows several types of fast routing protocols (packet filtering, QOS, cut-through switching) to be integrated into the network (internet) layer itself; these can then make decisions as quickly as a hash table can be accessed, which is all the more important considering the limited hardware this protocol was designed to run on.
This model has its disadvantages, but it seems that for the common usage cases it's better suited than the alternatives.
"What's wrong with a model where instead of every header identifying the next header's type, every header identifies its own type in a predetermined location?"
Because then it's effectively just the last byte of the IPv4 (or whatever lower-level protocol) header in all but name. It's a "chicken or egg" problem. You can't parse a header if you don't know what protocol it is.