Introduction to Cisco IOS XE

Hi Lazaros,

great, perfect. Appreciate your help.

1 Like

Hello, everyone.

I have a few questions regarding classic IOS. Does the term monolithic just mean that all processes share the RAM and CPU and that there is no isolation between them? So in other words, if one process requires more CPU and memory, it could end up taking way too much of it, so other processes would be starved? Since it’s “shared”. Another resource also says that “each process yields the CPU to allow others to execute” which is basically what Rene says as well.

I am referring to Rene’s example

For example, the “logging” process could require so many memory and CPU cycles that BGP is unable to perform some of its tasks. It’s also possible that when a single process crashes, it takes down the entire system. This is unacceptable nowadays in networking.

How does this work? Is there no prioritization when it comes to these processes? Wouldn’t BGP be considered as important as logging, for example? Because both BGP and logging are very important processes. Because, for example, a low-priority process can’t just take away resources from a process like BGP, can it?

Also, how does a single process crashing bring down an entire system? If the process fails or crashes, I thought its resources would be freed and given to other processes, I didn’t expect the possibility of it bringing down an entire system.

Thank you.
David

Hello David

In essence, yes. In classic Cisco IOS, “monolithic” means that all processes run in a single, flat memory address space with no memory protection or isolation between them. Specifically, all IOS processes (BGP, OSPF, logging, CLI, etc.) share the same memory pool. All processes are scheduled by IOS’s internal scheduler and share the same CPU resources. And there is no memory protection, unlike modern operating systems (Linux, Windows, IOS XE), where each process has its own protected memory space. In classic IOS, any process can theoretically access or corrupt another process’s memory.

So in classic IOS, you have one large program running directly on the hardware, not separate OS processes with individual memory address spaces.

Well, there is some prioritization, but it’s not as robust as in modern operating systems. Classic IOS uses cooperative multitasking, not preemptive multitasking.

In Preemptive Multitasking in modern OSes, the operating system acts as a strict enforcer. It gives each process a fixed time slice (e.g., 10 milliseconds). When time’s up, the OS forcibly interrupts the process and switches to another one, regardless of whether the first process is finished. This guarantees fairness.

In Cooperative Multitasking in classic IOS, each process runs until it voluntarily yields the CPU (e.g., when it completes a task, waits for I/O, or calls a yield function). The scheduler then picks the next process based on priority.

For the specific example, while IOS does have internal process priorities (Critical, High, Medium, Low), and BGP typically runs at high priority, the scheduler can only choose which process runs next when the CPU is available. If even a low-priority process contains a bug or enters a condition where it loops without yielding, or takes a long time before yielding due to its nature, then it can monopolize the CPU, resulting in inefficiencies.

Because all processes share the same memory space with no protection boundaries, if a process crashes, it may write to an invalid memory address, and it may corrupt memory used by other processes or the kernel. It may overwrite vital BGP routing tables, core IOS scheduling data or other critical system information, resulting in corrupted data. The CPU later tries to use that corrupted data and encounters invalid instructions or garbage.

Resources aren’t automatically freed because all processes run with unrestricted access to all system resources. A crash doesn’t cleanly free resources; it leaves the system in an inconsistent, unsafe state, resulting in haphazard allocation, often requiring a reboot. Does that make sense?

I hope this has been helpful!

Laz

Hello Laz

This was very helpful, thank you. As always, I have some further things to discuss :smiley:

This scheduler that you mention is called run-to-completion. Each process runs until it finishes or until the kernel decides that for whatever reason, it should no longer run and another process is picked.

Maybe I am not quite following but how many processes can be scheduled to run at the same time? Considering that IOS is a multitasking OS, it should be able to run more than one process but this makes me assume that only one runs at a time, until another one is scheduled? My book also says:

Run to completion schedulers are CPU efficient because the system does not need to
perform a context switch. A context switch is the capability for a single CPU to multi-
task between multiple processes.

Do you know how exactly is it? Are they trying to say that it’s not multitasking or how is it? :smiley:

Technicaly…. there are multiple processes running but it’s always one at a time? So multitasking just refers to the ability of the OS to quickly switch between each process to give the impression that the different applications are executing simultaneously?

Thank you.

David

Hello David

Wow, this brings back memories! I remember when multitasking was a topic that was really pushed by the marketing departments of companies selling operating systems for PCs. (This was over 25 years ago!!) They were talking about multitasking, but really, it is the illusion of multitasking that they were able to achieve.

By definition, multitasking is the ability of the OS to rapidly switch between processes to create the “illusion” that multiple applications are executing simultaneously. On a single CPU core, only ONE process actually executes at any given instant. And traditional monolithic IOS is designed to run on a single processing thread, so even if the underlying hardware has CPUs with multiple cores, only one core is leveraged.

So in such an arrangement, with the run to completion approach, each process runs until it finishes before the next scheduled process begins.

Hmm, this statement, although in essence correct, is a bit oversimplified and can be misunderstood. Let me elaborate a bit:

The point here is that run-to-completion minimizes context switching overhead. Keep in mind that:

  • Context switch = saving the state of Process A (registers, program counter, stack pointer, etc.) and loading the state of Process B
  • So in preemptive multitasking (IOS-XE), the OS forcibly interrupts processes at arbitrary points based on timer interrupts, requiring expensive state saves
  • In run-to-completion, processes yield at clean, predictable points where less state needs saving, making the switch more efficient

So the more accurate statement would be: “Run-to-completion schedulers are CPU efficient because they perform fewer and less expensive context switches than preemptive time-sliced schedulers.”

Yes, that’s right. This is true of both older monolithic IOS and the newer IOS-XE, especially if you have CPUs with only one core. If you have multi-core CPUs, then multiple processes can be genuinely run simultaneously, one on each core, but the OS must support this, and IOS-XE does, while IOS typically does not.

I hope this has been helpful!

Laz

Hello Laz.

Thanks again! I’ve some questions regarding XE now. I didn’t want to include them in a single post since answering that would take a week :smiley:

First of all, XE runs on a Linux Kernel. Resources often say that in classic IOS, processes have direct access to hardware.

Question 1

This means that any process can directly read, access and manipulate memory for itself or other processes in traditional IOS. Of course, correct code does not do this, which is why it asks the operating system to allocate or return memory – but it only does so because, in this case, the OS acts as a coordinator that keeps track of free and allocated memory to prevent collisions. However, the OS cannot prevent code with direct access to the hardware from accessing memory that it has not allocated to it.

With XE, my book says that only the Linux Kernel and its components can directly access the hardware. I assume that this is because IOSd runs as a separate process on top of Linux. My question is, does IOSd run in a separate memory space since it cannot directly access the hardware? So the Kernel has its own space while IOSd has its own space? Are there any platforms of abstraction?

Question 2

INE says that XE separates the control and data plane. This part confuses me the most. What does this mean? They say that the c/d planes were tightly coupled in classic IOS and that in XE, they are separated?

I’m not quite sure how to understand this. If the control plane fails, the data plane keeps going, or? :smiley: But if that happens, the data plane simply cannot run without technologies such as NSF/SSO or redundant supervisors.

Thank you!
David

Hello David

I believe that you have a good understanding of how it all works! Let me elaborate and clarify:

When we say that classic IOS processes have “direct access to hardware,” it means that IOS is the OS layer directly controlling hardware, with no protective intermediary.

IOS XE fundamentally changes this model. The Linux kernel runs in privileged kernel space and it has exclusive control over physical hardware: CPU, memory controller, network interfaces, buses, etc. The OS itself controls and manages process scheduling, memory management, and device drivers.

The IOS daemon (IOSd) runs in a separate, protected memory space from the Linux kernel. The Linux kernel has its own kernel address space, and each user-space process (including IOSd) has its own virtual memory space. The kernel enforces strict separation where one process cannot arbitrarily read or write another process’s memory (or kernel memory) without proper permissions and interfaces.

Hardware access is also mediated through kernel drivers and inter-process communication, not by the IOSd directly manipulating hardware registers. That means that if IOSd crashes, the Linux kernel and other processes can continue running, and the Linux kernel can restart IOSd without a full system reboot.

As for abstraction, yes, there are several layers of abstraction in IOS-XE, where the Linux kernel sits between the hardware and the platform/forwarding processes, which are Cisco-specific daemons that perform the device functions.

What is meant by this is that where the monolithic IOS image implements both the control plane and the data plane using the same image running on the same CPU, the IOS-XE decouples these functions into separate and distinct processes. This does have some specific advantages.

The control plane runs as an IOSd in the Linux user space while the data plane is implemented in dedicated hardware forwarding engines, depending on the platform. Specifically:

  • QFP (Quantum Flow Processor) on ASR 1000 and ISR 4000 series devices
  • UADP ASICs on Catalyst 9000 switches
  • Other platform-specific ASICs/NPUs

These are managed by separate platform processes. The purpose of this separation is not so much to allow the control plane to continue to function if the data plane fails or vice versa. As you suggest, this is not useful. The point is that there is performance isolation, fault isolation, and better process management. If the control plane does indeed fail, it can be restarted with limited disruption of the data plane, for example.

I hope this has been helpful!

Laz

Hello Laz.

Great, so happy we managed to discuss all this.

So here comes the final one, XR.

  1. Does XR have some form of a startup config? It does load the configuration upon boot but there is no specific “startup-config” that I found..
  2. Have you actually seen these used in the real world? I didn’t even hear of XR until I started with SP.
  3. What’s up with the naming of the interfaces? G0/0/0/x. I thought the first 0 is the linecard, the second 0 is the interface module, and the third 0 is the specific interface. Yet there are 4 values in Gx/x/x/x.
  4. Does IOS-XR only run on modular (Chassis devices)?

Thank you

David

Hello David

No, not in the traditional IOS/IOS-XE sense. IOS XR uses a fundamentally different commit-based configuration model. For the traditional IOS/IOS-XE approach, we have:

  • running-config (in RAM)
  • startup-config (separate file in NVRAM)
  • You must manually sync them using copy run start or write memory

But in IOS XR:

  • When you enter configuration mode and make changes, you’re editing a candidate configuration
  • Nothing is active until you type commit
  • When you commit:
    • Changes are validated and applied atomically to the running system
    • The configuration is automatically saved to a persistent configuration database (SysDB) on disk
    • No separate “save” step is needed

On reboot, IOS XR loads the last committed configuration from this database. So the committed configuration serves as both your running config and your “startup” config… they’re always synchronized.

Absolutely! It’s the dominant OS in Service Provider networks worldwide. That’s why you haven’t seen it until you started working with SPs. You won’t see XR in enterprise branch offices but in SP cores and large-scale routing environments, IOS XR is the standard. For this reason, typically, you won’t see very much of it in CCNA or CCNP certifcations or labs ether.

However, IOS XR is deployed extensively on major platforms like the ASR 9000 Series, which is arguably the most popular SP router globally!! Other devices include:

  • NCS 5500/5000 Series - high-density 100G/400G backbones
  • NCS 540 Series - 5G mobile backhaul/fronthaul, metro aggregation
  • CRS Series - legacy core routers (Carrier Routing System)
  • 8000 Series - newer silicon-based platforms
  • XRv/XRv 9000 - virtual routers for labs and NFV environments

The four-part naming reflects the rack/slot/module/port hierarchy in modular SP platforms. This is generally standard for SP deployments. For example:

GigabitEthernet0/2/0/5

  • Rack (0): Physical rack or chassis location. In multi-chassis systems (where multiple physical chassis are clustered to appear as one logical router), this distinguishes between chassis (0, 1, 2, etc.). For standalone routers, this is always 0.
  • Slot (2): The physical slot number where the line card is installed in the chassis.
  • Module (0): The sub-module, daughter card, or interface module on the line card. Even if the line card is fixed with no sub-modules, this field remains and is usually 0.
  • Port (5): The specific physical interface port number you connect cables to.

So GigabitEthernet0/2/0/5 means: Rack 0 (standalone), Slot 2 (line card), Module 0 (first module), Port 5.

No, IOS XR runs on modular, fixed, and virtual platforms. While IOS XR was originally designed for large modular chassis, it’s now available across multiple form factors.

This means you can use the same IOS XR operational practices (commit/rollback, interface naming conventions, configuration syntax) across massive core chassis, compact edge routers, and virtual lab environments.

I hope this has been helpful!

Laz

Hello Laz.

Perfect, thank you!

On reboot, IOS XR loads the last committed configuration from this database.

About this part here. The SysDB is this?

My question is, what is mean’t by “IOS XR loads the last committed configuration?”.

If we take a look at the last config that I committed

this configuration only enables the two interfaces, the rest of the configuration is contained within the other commits that I’ve made

Does XR load all of these or what is mean’t by the fact that it loads the last committed configuration?

Also, is it okay for me to provide configuration in screenshots this time? It saves me some time and no one will copy it anyway since it’s just a show command output.

Thank you
David

Hello David,

Great question! Let’s dig a bit deeper into the IOS XR’s configuration model. When we say “last committed configuration,” it’s a bit more involved than just that simple statement.

Each commit command creates a separate commit entry in the commit list. This is done to keep a better record of changes that are made to the OS. However, the “last committed configuration” refers to the complete, cumulative running configuration as it exists after all commits have been applied, not just the changes from your most recent commit. Keep in mind that each entry is not a separate file, but simply a record of the commit.

In your case, commit 1000000016 includes the two interfaces you enabled in that commit. But the complete configuration contains the results from that commit, PLUS all configurations from earlier commits all the way back to 1000000001, even if some of those modified the configs of even previous commits.

Like I said before, each commit entry is not a separate file. The running config is a single file which is the result of all the recorded commits. So the complete configuration you’d see with show running-config is what gets loaded on reboot, not just the two interface commands from the last commit.

Yes of course, that’s fine, thanks for asking!

I hope this has been helpful!

Laz