pigeon background: the osi network model 🕊️
Paul Tagliamonte 2026-09-08 diyOne of the most practical ways to avoid dealing with edge-cases is to pretend they don’t exist and say “well that’s not REALLY my problem”. You may very honestly report a status of “no blockers! ✅” up the chain and if/when this comes to bite you, it’s now important enough and far along enough that it’s not your work (of course), so it must be the thing (insert “on top of” or “below” here) your code. You, of course, don’t want their edge-cases to bleed through “abstraction layers” because of one “bad design” that “shouldn’t have been like that to begin with”. On top of that, solving it in your code is (insert one of “unmaintainable”, “not modular enough”, or “adding too much tech debt”).
The solution in that case is simple! Just invent a new abstraction, and wedge it between the two things you have, rather than contend with the essential complexity. Problem solved. None of the big brains were wrong, reality can continue to be ignored, and you now have an ablative layer to shield engineers on both ends from learning otherwise (uh, don’t worry about that bit, it’s just an edge-case for some old code). Mission Accomplished. Just like cuttlefish, modern software engineers will, when confronted with a predator, throw out a ink cloud of “abstraction layers”, “normalized ontologies” and “ETL pipelines” and make scarce for a few weeks (building five new libraries).
Let’s talk about the OSI networking model:

The ISO standard Open Systems Interconnection (OSI) model is the gold standard in terminology regarding naming networking anatomy, first created in 1978. I had to learn it (and was tested on it!) as part of my computer science degree, and the names have legitimately proliferated everywhere. Even this blog post is framed largely along the splits defined in the OSI model.
| Layer | Name | Description |
| Layer 1 | Physical | How electricity carries data (ethernet, wifi) |
| Layer 2 | Link | How data is formatted (also: ethernet, wifi) |
| Layer 3 | Network | How to get from computer A to B (IPv4, IPv6) |
| Layer 4 | Transport | How to send a variable amount of data (TCP, UDP) |
| Layer 5 | Session | Things that handshake go here |
| Layer 6 | Presentation | Data encoding (JSON, XML, ASN.1, encryption) |
| Layer 7 | Application | Protocol-specific messages (http, ftp) |
Easy peasy. Good to go. Now we can just bin things in the right place, and we
can swap things in and out as we need them. After all, if I can send IP over
Avian Carriers, why do I need to
know what my link-layer is when I send a cURL? I don’t, really! Even with a
“normal” network, I can’t really tell when it’s using IPv6 or IPv4 without
looking closely for IP addresses in the logs. A true testement to the Layer 3
abstraction layer.

Naturally, these layers nest – a well-formed Layer 1 is used to carry a Layer 2, which contains a Layer 3, and then – well – you get the idea. The OSI model is like an onion – it has these nice layers that cleanly separate, are slightly translucent, and peeling them back will make you cry.
Let’s dig in.
AX.25
Sometimes, the layers can break down a bit. One such (topical for this blog series) example is AX.25, which is based on the ITU standard X.25 protocol. X.25 (and AX.25) is, at minimum, a combined layer 2 and layer 3 – responsible for both the addressing and formatting of data between links, and also how to route messages across the network. Although the OSI model was created in 1978 (predating X.25), the OSI model wasn’t an ISO standard until the 80’s, so we’re going to just give them a pass. After all, the 80s were a wild time. For those of you unfamiliar, the ITU is an international organization founded by Napoleon III, nephew to the OG short king. The ITU has bestowed upon us such croud favorites as ASN.1, LDAP, x509, and RDP, not unlike prometheus descending Mount Olympus.

OK, so, AX.25 must just be a kooky exception, and, for better or for worse, the Linux kernel support for AX.25 was removed recently – so perhaps it is just a bit of a one-off thing. Let’s just move along, I mean, everything since the 80s should roughly look like the OSI model though, right? After all, we’ve taken great pains to indoctrinate graduates into this system, and all “real” engineering work since then fits neatly into this model.
Well, you’d think that!
SFP Modules
Let’s start with one that’s a bit unfair. If you want super fast fiber optic connections, you’re gonna need to spend a lot of money on SFP-like modules (SFP+, QSFP, etc etc). This “standard” form factor plugs into your extremely fancy managed equipment, and is responsible for scalding your fingers and taking Layer 2 (in every case I’ve seen personally, some version of Ethernet) in order to turn it into frickn laser beams. This is, very (very) obviously a “Layer 1” function.
There’s one asterisk – there’s a few “Smart SFP” modules out there that run an entire Linux system on the transceiver. Yes, really.

“Sure”, I hear you crying out loud, “Sure, but it’s only the management side – it’s fine, it’s just sitting off on the side!”. There is some truth to this, I guess – I mean, the SFP module’s remora fish-like operating system has its own network interface wedged in (not to be confused with the fiber optic connection) that has less than a Gigabit to the host. It doesn’t really even use the PHY at all, it’s purely Layer 2 via the SFP interface – so like, it’s fine! Is it even REALLY part of the Layer 1?
I would usually give up around here, but I was wronged once and refuse to let it go. In my case, the PHY being down caused the Linux system to not fully come online (I wanted to see the management end without plugging it in, but like, sure why not, makes sense I guess), but also the Linux system not coming online (yes ok I was fucking around with it, I am not blameless – nevertheless –) meant that the PHY won’t come up (makes “sense”). Therefore, I claim, there’s a dependency there – it’s essential to the operation of the transceiver. While it’s true it’s not the thing modulating laser carriers, it sure doesn’t feel unrelated entirely. It’s not a Layer 2, and it’s definitely more than a Layer 1, but like, can we say it’s anything other than a Layer 1? I don’t think we can.
OK, I’ll get off my soap box now. Like I said, perhaps this is unfair. It’s not even a good example, frankly. Let’s pick on someone our own size.
Let’s talk about TLS.
TLS
Transport Layer Security,
or as the kids call it: TLS,
is responsible for the security and integrity of basically all modern
traffic over the internet. I’m not going to clown on TLS, it’s good shit. We
should all use it everywhere we can (oh right, forgot where I was for a second,
we can’t use TLS while doing ham radio, strike that from the record please).
TLS grew out of an even older spec from the olden days (and also still today in some
places I don’t enjoy spending time) of netscape named SSL. The
“SSL” acronym expands to “Secure Sockets Layer” - because, i’m assuming here,
it’s a secure socket. Perhaps keen observers will already see where I’m going
here, which is that my personal headcannon is that big OSI networking model
caught wind of this, showed up to the standards meetings, and flipped tables
until the crypto nerds agreed to use the OSI approved term for a socket,
which is a TRANSPORT LAYER, ya goofs (editor’s note: this is a joke, please
don’t come for me too, big OSI model).
But hey – that’s it, right! It’s using the OSI approved word and terminology! It’s TRANSPORT LAYER security. It’s very VERY obviously a Layer 4 (Transport), and we even use it like one (we can swap TLS out for TCP, bingo bango good to go).
Wait, but, if TLS provides a Layer 4, upon reading the spec, it seems like
TLS implies the existence of some established transport (Layer 4) already! I
mean, I guess this makes sense since TLS is generally used over TCP (https,
for instance, is TCP port 443 – sometimes UDP for you DTLS RTP types).
Also, since it’s always the example used, I also know that TCP is, like,
the Layer 4, and surely a Layer 4 can’t contain a Layer 4 – the layers
nest damnit.
Hold up, even further along it looks like there’s some handshaking and session
establishment in here. That’s a layer 5 concern! We can’t — What the hell,
no, wait, obviously TLS does encryption – this thing is encryption! We all
know that encryption is part of the Layer 6 definition. It’s got to be
Layer 6.
That’s got to be it, it’s not like there’s any way this thing is part of Layer 7, right? RIGHT? Wait – shit, I’ve extensively used TLS inside a Layer 7,
that’s right. mTLS is widely used as part of web application login,
screenshots of cert selection dialogs and all. I bet some of you out there will
take issue with this one, but I’ve seen a LOT of Layer 7 (and above; docs
count) code out there dealing with the specifics and logic surrounding mTLS -
not to mention authorization and access control for APIs.

I wonder what layer that makes a WebSocket over HTTPS…. — wait snap out of
it. All this doesn’t even deal with the inconvenient reality that SMTP
handshakes can (and do) negotiate an upgrade to TLS over the existing session.
This puts a Layer 7 (SMTP) inside a Layer 4 (TLS) where the handshake
(allegedly a Layer 5 concern, but…) took place in a Layer 7 (SMTP)
connection over a Layer 4 (TCP).
TLS defies analysis. One is forced to deal with the fact that protocols may not always be well-ordered according to the OSI model (hearsay, nay, heresy!), and that this abstraction is not always helpful, or one has to come up with lots of post-hoc retcons to make this one OK. I haven’t looked it up, but I have a sneaking suspicion about which one of the two I’ll find if I go looking.
This same story also applies to things like QUIC (QUIC is inside TLS inside UDP) – but best not dwell on such things. TLS (and even QUIC) is at most some sort of admission that a Layer 4 can contain another Layer 4 and the rules have not been broken - don’t worry about the rest of that stuff encryption handshaky stuff. The OSI model holds, and we can move on. It’s a Layer 4, it’s in the name and everything, the rest of that stuff is just poor design.
It’s not like we’d be transporting Layer 2 over a Layer 4, right?
VXLAN
Back in 2014, some intrepid engineers sketched out VXLAN out of what I assume was (very) justified frustration with Ethernet’s native VLAN regime (usually VLAN means IEEE 802.1Q, but not always. I’m just going to roll with 802.1Q here). Actually using 802.1Q VLANs in production requires a lot of cooperation from (more expensive) switching equipment, reconfiguration when VLANs change, and has no shortage of security footguns.
On top of that, the new industry best practice cloud native approach is much smarter than all that old shit – we want to manage our network flows by talking southbound to our data plane service mesh orchestration system, dynamically adjusting our SD-WAN to support dynamically changing workloads – and of course, since we just spent our whole budget on that, those expensive switches are out.
The solution is clear – let’s take the Ethernet frames, box them up, put them into UDP jumbo frame packets, and send them across our high-value plain ole' unmanaged regular switch core network between nodes.

I, personally, don’t really have an opinion on (nor do I really care to form one)
if this Packet Heighliner (thanks mikey for that joke)
is best thought of as a Layer 2 or Layer 4, but you could make a
pretty strong argument for either depending on your point of view. Heck,
VXLAN is even implemented in kernelspace these days.
FWIW, I actually genuinely think this is a pretty sweet setup, and I’ve
definitely used VXLAN for real before (and will again!), with only one
warning
about the Linux kernel implementation (it treats the VXLAN local IP as a
source default, not as an address to bind to). It’s a great solution, and even
though i’m picking on VXLAN a lot, this is actually a very well trodden path
with tons of prior art (see also: ip-in-ip, sit, ipsec, l2tp, pptp, wireguard,
etc etc). That really doesn’t change things for the OSI model – this all means
we now have used a Layer 4 (UDP) to carry (and inject into the host network
interface) a Layer 2, which may contain anything up to and including Layer 7
data.
So that’s it then. The OSI model is still there, but trying to apply any sort of meaning as to what type of data will be going over each layer is not a great adventure to be on.
Not to continue to beat a dead horse, but even in the course of this blog
series, I’ve transmitted (and received) pigeon frames over my HTTP/2-based
protocol named riq – just to spell it out, I put a Layer 7 (HTTP cURL)
inside a Layer 1 (pigeon), as raw IQ values for transmit, inside a Layer 7
(riq) inside a Layer 4 (TLS) inside a Layer 4 (TCP) inside a Layer 1
(10GBASE-T).
Not only does an OSI network layer contain data “above” it in the model, but it also can contain data at the “same” level, or even “below” it. Anything can really contain anything, and any efforts to properly nest things is going to be a bad time. I’ve increasingly lost the point as to what we were even doing in the first place by attempting this exercise – and yet we keep teaching it in schools.
As for myself? I’ve just given up on trying to pin things down to where specifically they live in the OSI networking model.
I do have some sympathy in continuing to ascribe meaning to some of this stuff,
– but putting any more resolution on the difference between Layer 5 and
every layer above it is just not worth it for me anymore, so I’ve stopped doing
it. Layer 4 is only really useful in so far as you can say “we have some way
to talk to this other computer” – but putting a sticker on itas to how that
fits into the stack is perhaps not as important as it once was – and really
doesn’t tell you a lot about its design and dependencies.
I will be fairly sympathetic to those of you reading this who decide you no
longer care about the difference between a Layer 1 and Layer 2 – which,
fair enough. My two cents is that the physical media and link layer tend to
usually be pretty tightly coupled – but the relationship is usually driven by
the Layer 1 always using some specific (perhaps common) Layer 2. As a result,
for my money, there is still a useful distinction here (for example, LTE and 5G
use RLC, 802.11 WiFi standards like ac, ax, and be use the same WiFi layer
2, and both fiber optic and copper links use Ethernet as their Layer 2),
so I’m going to continue to use it.
With that out of the way, we can dig in on some of the work I’ve done on pigeon, now fully understanding where it lives in the network model. I hope this overview was helpful. eat at arby’s.