 Hi, and welcome to this talk entitled Calico VPP, using Calico's Plugable Data Planes for Fun and Fast Networking. My name's Chris Tomkins. I'm a developer advocate at Tigera. I champion user needs and support the community and users. I've been working in networking since about 2000. And after a few years, I realized that a per device CLI is not a great solution for a large environment. So I took an early interest in infrastructure as code and automation. And I still pursue those today. When I'm not working in IT, I love reading films, music. I also fly radio-controlled gliders, which is a strange coincidence. As our other speaker today, Alois Augustin, who's a software engineer at Cisco, also does like flying radio-controlled planes. He is one of the Calico VPP Datapaint Author team. So without further ado, let's get started. So I'm going to start and just talk a little bit about Calico, first of all, just very briefly. So what is Calico? Well, it's an open-source networking and network security solution for containers, virtual machines, and native host-based workloads. It supports a broad range of platforms, including Kubernetes, OpenShift, Morantis, Kubernetes Engine, OpenStack, and bare metal services. And whether you opt to use the EBPF data plane or Linux's standard networking data plane or VPP, or the Windows host networking service data plane, Calico delivers blazing fast performance and cloud-native scalability. It provides developers and cluster operators with a consistent experience and a set of capabilities, whether you're running in cloud or on-prem. So we have more than 6,000 Slack channel members, more than 150 contributors, and more than a million compute nodes are powered by Calico every day. So when Calico was designed, it was designed with a four-tier architecture from day one. So software modularity and software loose coupling were included by design in the software architecture, and that has paid great dividends. So you might be aware that network hardware is often designed with a paradigm of having a control plane and a data plane. We'll go into what those are in a moment, but Calico also follows that model. Software modularity is the concept of the dividing software code intentionally into blocks that work together to create a larger whole, and software loose coupling is the concept of making these blocks opaque to each other so that they can only talk via strictly defined interfaces. Together, these concepts make the software easier to fix, troubleshoot, and replace. And in the case of Calico, these benefits extend to following the network paradigm of a control plane and a data plane. So you can see that I've highlighted in blue here the control plane elements of the four tiers that Calico are made up of. So the control plane elements are the data model, which defines the custom resources used to enable Calico and the Felix calculation graph, which is the control plane that makes the smart decisions. And then the data plane components are the data plane driver, which is a simple and minimal driver for programming the data plane, and the data plane itself, which is responsible for actually forwarding packets. So let's have a look at a more detailed of the control plane data plane concept. So this diagram shows three nodes, three network nodes. Now, each network node might be a compute host, a hypervisor for virtual machines. It might be a container host, it might be a router or a switch. But you can see conceptually, each node is made up of a control plane at the top and the data plane at the bottom. The control planes talk to each other through the data plane, but their job is figuring out what's going on in the network and establishing consensus. For example, routing protocols. So the control plane is typically implemented on a general purpose CPU. It manages complex device and network configuration and state. And if you're familiar with routing protocols, such as BGP, OSPF, and ISIS, they're implemented in the control plane. So it's necessarily sophisticated software. There's a lot going on there. And that's why it runs on a general purpose CPU, which is appropriate for running workloads that can vary in software complexity. The data plane, in contrast, is a different beast. The data plane's job is actually to forward the traffic. So I've put cat videos in the diagram because let's be honest, that's 90% of the internet. And you can see that the cat videos only travel through the data plane. They don't travel through the control plane nodes. So the data plane is responsible for processing the transit traffic through the devices. It needs to send a lot of traffic, so it should be able to use hardware acceleration features if they're available. It should be designed to be the simplest possible implementation of the required packet forwarding features because it implements a fast path for the traffic, so the less software complexity in the data plane, the better. If there are hardware acceleration features available, like ASICs, they should be used. And I like to use this metaphor, or example, really, of MPLS, which is a common tool in service provider networks. MPLS has been enormously successful in service provider networks, and that's because it purges unnecessarily functionality from the data plane and performs minimal packet processing per packet, and that leads to fast, affordable devices. So MPLS, the designers looked at what was strictly necessary, and some of the functionality that's in IP, such as variable length subnet masks and checksums, which adds a great deal of complexity, are not strictly needed in the MPLS network. So Calico benefits in the same way by looking at what is actually strictly necessary in the data plane and offering data plane choices. So there are some benefits of control plane and data plane separation. The first is that you get specialized, minimal data plane code, so you're keeping the data plane code as small as possible. It's lean, and that carries many benefits. For example, if you have only the minimal set features, then each line of code can be groomed in more detail from a security and a performance standpoint to make sure that it's strictly necessary. Makes the code easier to audit and easier to keep performance high. Also, by having a targeted data plane feature set, then not every deployment is the same. You might find that one deployment needs compatibility with older kernels, or another deployment needs high cryptographic throughput, and having a targeted data plane feature set allows you to use a different data plane to solve each use case. By reusing the control plane code, control plane code reuse, you avoid rewriting that necessarily complex software code, and that code can be more stable, which makes it easier to harden, easier to troubleshoot, because it doesn't change when the data plane changes. The next advantage is future proofing. We've all seen technologies that are going to be the next big thing, but it doesn't quite work out. My favorite example is Trill, which stood for transparent interconnection of lots of links. And back in about 2014, this was gonna be the next big thing in networking, but it never came to fruition. By supporting multiple data plane technologies, Calico is able to adapt to a wide range of environments and use cases, and this will continue in the future. The next advantage is adaptability. If a new data plane technology appears on the horizon, then the Calico community is able to quickly get a working test, and to evaluate whether this is something we want to pursue further. And the final one is agility for the user. If you have multiple data plane choices, then you're not locked to a particular data plane. You can make the right choice today, and maybe the right choice in the future remains the same, or maybe it changes, and you can continue to deploy a data plane that's appropriate for your needs. So we're nearly ready to talk about VPP and what VPP can offer in this scenario, but before we do, we should just talk about the three other data plane choices that we have today. So we have the Linux IP tables data plane, which is our original data plane. It's heavily battle tested. It offers good performance, great compatibility, and wide support for a huge range of device types. The Windows host networking service data plane, which offers Windows container deployment and securing those workloads, and it works in any cloud computing provider or on-prem. And finally, we have the Linux EPPF data plane, which scales to higher throughput and uses less CPU per gigabit, reduces first packet latency to services, it preserves external client source IP addresses all the way to the pod, and it supports direct server return for better efficiency. If you want to hear more about any of these data planes, we've had pre-existing talks that you can search for, which discuss all of these. If you look for my name, Chris Tomkins, and EPPF, you'll see those talks. But today, we're not talking about these data planes. We're talking about this fourth option, which we're really excited about, which is VPP and what that can offer with Calico. So without further ado, I'm going to let Alois take over from here and he's going to talk to you, but specifically about the benefits that the VPP data plane offers. Hi, everyone. Thank you, Chris. Before we dive into the data plane, you may be wondering what VPP is. And it's been presented quite a few times already, so I won't spend too much time on it. But in short, it's a user space network data plane. So it's a software router and it's highly optimized both for packet processing and at the API level as well. It supports all kinds of hardware and it's easily extensible through plugins and that's something we used in the Calico integration. It leverages vectorization to maximize the CPU instruction and data cache efficiency and that's leading to some pretty impressive performance number as shown here. So these numbers were obtained on standard 2 Socket Ice Lake servers. And doing IPsec, we can get one terabit per second of encryption and when doing simple forwarding, we can reach 1 billion packets per second. If you'd like to learn more about it, there are plenty of presentations available out there that you should be able to find quite easily. Now for the Calico VPP integration, what we do is that we use VPP as a data plane for the pod traffic in Calico. When you deploy Calico VPP in a Kubernetes cluster, you'll get one VPP instance on each node that processes the container traffic. It will implement the CNI, meaning it will create and configure the interfaces within the pod. It will also route this traffic, of course, and implement all the specific features required by Kubernetes. So that includes policies, service virtual IP load balancing, potentially source netting the outgoing traffic and all the other Calico features. There's the encapsulation as well, of course. It can do IP IP, VXLAN, wire garden encapsulation. And all this logic is done in dedicated VPP plugins, which are optimized for this use case. We wanted to make it as easy as possible for users to deploy. So if you want to deploy Calico VPP on a cluster, in addition to the Calico configuration, the only thing you need is to pass an interface name to VPP that it will use as the Unplink interface. And everything else will be taken care of automatically. You should have a working configuration out of the box. Now, you may legitimately wonder why we're doing all this. After all, Calico is working perfectly fine and it's been doing so for quite some time now. And so here are some example use cases that VPP will benefit to. The first one will be internal encryption. So as we've seen, VPP has an extremely performant IPsec implementation. So we can use that to encrypt the traffic between nodes, basically at line rate at 40 gigabits per second. The second use case would be exposing highly available services. We're using Maglev as the load balancer implementation for Kubernetes services. Maglev is a consistent layer for load balancer. And basically it allows connections to survive node failures. And it also does DSR, direct server return, which will reduce the global networking load on the cluster if you enable it. A third area where VPP is very helpful is if you have custom networking requirements. This is very broad, but some examples would be if you need custom encapsulations, maybe IPv6 segment routing or Genev, things that are not supported by the Linux kernel. Or maybe if you want to integrate with the network service mesh, NSM, or some other specific SFC technology. Well then, VPP brings a lot to the table because since it's managed like any other infrastructure service running on the cluster, you can very easily modify or upgrade it. And finally, we have network intensive applications and that's gonna be what we'll focus on today. What I mean by network intensive applications is applications that spend most of their time doing network IO and potentially crypto for encrypted protocols such as TLSN Quick. There are various applications that fall into this category. That could be for instance proxies, distributed storage applications, content servers, VPN endpoints, network functions, and so on. With these applications, at some point, the network stack that you get in the Kubernetes with this interface to the pod becomes a bottleneck. And the usual solution is to bring a physical interface directly into the pod with SRIOV. But the drawback if you do that is that then you will be on your own for all the addressing, routing, network policies, and so on. So with Calico VPP, we are adding some alternatives that can offer very high performance without going out of the regular Kubernetes network model. So to understand where these optimization opportunities are coming from, first let's go back to the regular Calico networking on the node. So this diagram here is what you would get with the IP tables or the EBPF data planes. Basically applications are using the Linux kernel syscalls to send and receive data. Then this data is processed and converted into packets by the kernel transport stack. And then it goes out of the pod through this interface. Then all the Kubernetes networking features are implemented in the kernel with the data planes that's been configured. And finally, the packets go out to the physical network through the uplink interface. Now with the VPP data plane, things are a little different. The applications running in the pods still use the regular syscalls to send and receive data. But instead of a viz, this data is sent on a tune interface when it's exiting the pod. At the other end of this tune, there is VPP, which will take care of the Kubernetes networking features implementation. And eventually it will send the packets out through the uplink interface. One thing to note is that this forces two copies of the data. A first copy when the data is sent by the application. So this one you'd also get with regular Calico as it comes from the Soget API. And a second copy when the data goes back to VPP in user space. This extra copy is a source of inefficiency, but VPP is tailored to the requirements that we have for this use case. And it's faster than the kernel so it more than makes up for this extra copy. As we've shown in previous talks linked here, it is as fast or faster than the other data planes in most situations. So this is good as a default because the performance is okay and applications can run unchanged and the VPP data plane is completely transparent for users. However, if we have very high network requirements and if we are looking for performance optimizations, can we do better than this? The answer is obviously yes. And in theory, it's simple. We should just send the data directly from the app to VPP and bypass the kernel entirely and save at least two data copies in addition to all the processing that the kernel does. In practice though, it's going to require a bit of effort to do so. But we've tried to make it as easy as possible. So we have actually two different options targeted at different kind of applications. So we'll make a distinction here between two categories of network intensive applications. The first one will be packet processing applications, which could also be called network functions. These applications are primarily caring about layer two or layer three packets and they process these packets. And for these applications, we expose MIMF interfaces in the pods. The second category will be what we call endpoint applications. So these are more your traditional applications such as proxies, content servers, storage servers and so on. And these applications don't care about packets. What they're interested in is TCP connections or maybe even TLS or quick if they encrypt their data. And for these applications, we expose the VPP host stack in the pods. Before we dive into the specifics of MIMF and the host stack, one thing I'd like to mention is that if you enable either in a pod, then the pod will still have its regular two-tap interface available. This is useful because it allows to have some containers or applications in the pods that can still communicate with the outside normally without requiring any changes. So this is useful, for instance, for the supporting processes, for log collection, maybe configuration, things like that. So let's dive first into the MIMF interfaces. What are MIMFs? They are very simple, highly optimized software interfaces. They're relied on a shared memory segment. They allow to exchange packets between two processes. Just a very simple process, just sending or receiving packets on a MIMF interface can transfer more than 15 million packets per second on a single queue with a single core. And that's around one order of magnitude more than what you can normally get in a Kubernetes pod. Calico VPP can make one MIMF interface available in the pod, and then the application running in the pod has a few options to use this interface. If the application is based on DPDK, it can directly use the MIMF as DPDK has a MIMF driver. This will only require configuration changes to work. If it's a C application, you can use libMIMF to leverage the MIMF interface. And for goaling applications, there are two options as well. The first one will be golibMIMF, which is a C go to wrap the C library. But I would recommend you use the second one, which is called goMIMF, which is a pure go implementation. But there's a third option as well, which does not require writing any code, and that's to run VPP in the pod. VPP, of course, supports MIMF, and it can be configured to easily implement various network functions. And the nice thing is that it won't need elevated privileges to connect to a MIMF interface. It can just run in as an unprivileged pod. Here's an example of a trivial application using goMIMF that you could run in a pod. As you can see, the API to send and receive packets on an interface is quite simple. There's a readPacket and writePacket method, and you get the packets in byte slices. This is a trivial example that just swaps the source and destination IP addresses. In practice, you'll likely want to do more elaborate things on each packet, but you get the idea. And finally, if you want to enable MIMF interface in a pod, then that's very simple. You simply need to add an annotation like this in the pod definition. One thing to note is that since there is also a Tune interface that can send traffic to the pod, VPP, when it receives a packet, it needs to know where to send the incoming packet, either to the Tune or to the MIMF. And this is done based on destination ports. You can specify in the annotations which interface will be the default interface, either the TuneTap or the MIMF. And then for the other one, you can specify a few ports or ranges of ports which should go to that interface. That's it for the MIMF, but now if you don't really care about packets, if you're a few rather handled connections, like a normal application developer, well then there's the host stack. And the host stack is the VPP transport protocol stack. So like the kernel VPP implements, there are layer four protocols that you're familiar with, TCP and UDP. It also implements higher level protocols that you can use directly, such as TLS and Qwik and DTLS as well. The host stack has an API for each of these protocols which is based on a shared memory segment just like MIMF. And we can make that API available in a pod. In order to use it, the application running in the pod should use the VPP communications library, or VCL in short. The VCL is a C library that provides a relatively high level API for the host stack and it's pretty close to the traditional BSD socket API, which makes it quite easy to use. Here is a summary of the VCL API. It should look fairly familiar. You have the expected listen, accept and connect calls that you're probably used to. And you have a select and E-Poll implementation as well. Of course, it requires a bit of effort to integrate an application with the host stack because you need to swap the networking for the host stack networking. But there are some apps which are already integrated with the host stack. So that will make it easier to get the benefits of the host stack. We have an Hyper3 integration for throughput testing. We have NGINX as well, where the host stack can really accelerate content serving. But the most interesting here is probably Envoy. Envoy is a very famous new layer seven proxy, which is used in the STO service mesh. And since it's a proxy, it's just forwarding HTTP requests. So it's a great candidate for optimization with the host stack. We don't have yet a fully tested integration with Calico VPP and Envoy and the host stack, but we are hoping to be able to provide that soon. Now here are a few numbers to show you what the host stack is capable of. These are pretty good numbers, but one thing to keep in mind is that they are taken from host stack benchmarks outside of Calico VPP. Unfortunately, I don't have benchmarks within Calico VPP available at this time. However, there should be some in another Calico VPP presentation that Nathan is doing with Chris at the Open Networking and Edge Summit, which is a co-located event. So if you're curious, I encourage you to go listen to that talk as well, and you will have a lot more performance data points there. Now, as you can see in the example here, the host stack can be simply enabled for a pod with an annotation, just like the MIMF. Unlike the MIMF though, there's no need to specify which traffic should go to the host stack as this will be done automatically. If there's a host stack connection for listeners that matches an incoming packet, then that packet will be sent to the host stack, and otherwise, it will be sent to the ton. So it should be really straightforward to use. That's it for the host stack. There are a few other things to note that apply to both MIMFs and the host stack. The first thing is that for all the traffic that goes through either MIMF or the host stack, then the regular Kubernetes networking features will apply. This means policies will work as you expect, service load balancing will work as well if you connect to a service IP, et cetera. Secondly, if you want to, for some reason, it's also possible to use both MIMF and the host stack in a pod. And finally, MIMF and the host stack are exposed within the pods using abstract tuning sockets with the names shown here. So, to summarize, here is a table that compares the different ways to process traffic in a pod in a Calico cluster. It's split into two sections for the endpoint connection-oriented applications and for the packet processing applications. For endpoint applications, we don't have definitive numbers yet for Calico VPPs. This is still a work in progress. But we expect the host stack to provide a substantial performance boost. It's usually a few tens of percent, so 30, 40 percent performance boost. And when crypto is in the picture, the performance boost is likely even higher. For packet processing applications, the order of magnitude of performance that we expect in Calico VPP is around 10 million packets per second, per queue. That's according to the very early testing that we did. But again, this is still a work in progress. It will require more testing to get real numbers and scaling characteristics. And without Calico VPP, if you would like to get the same features today, well, then the application could use an AF packet or AFX-DP socket under this interface in the pod. So this has several drawbacks. However, first, the pod will require some additional capabilities to run. But also the performance, as far as we've seen, is way lower than with VPP. It's around one million packets per second. That's it for the MIMF and host stack presentation. What we've shown here has some very interesting potential for some applications. But the broader point I'd like to make before I hand it back to Chris is that the Calico VPP data plane makes it very easy to extend and experiment with the Kubernetes network. This presentation was focused on high-performance networking apps. We've shown that it's possible to run them in a regular Kubernetes cluster. But it's not just about performance. VPP really unlocks a lot of possibilities in terms of what it's possible to do in Kubernetes with a lot of velocity as well. And we are really excited for all the things we'll be able to do with it. And it's not just us, because this is all open source. Anyone can contribute anything. And if you have any sort of idea, we'll be very happy to talk with you about them. Really feel free to reach out to us either on GitHub or on Slack. Thanks, Alois, it's fantastic tech. So in summary, this is a new VPP-based user space data plane for Calico. It brings networking features that were previously only used by service providers to Kubernetes and allows the managing of high availability and high-performance networking apps in Kubernetes. So that's nearly it for this presentation. We have a number of new exciting features on the horizon, including maglev load balancing, packet-oriented interfaces, and hopefully soon general availability in Calico. Currently, the project is expected to move from tech preview to beta status in V321 or V322 of Calico. So if you'd like to stay up to date on the project, don't hesitate to join the VPP channel in the Calico user Slack. We publish our releases there, and the Calico user Slack is a really active community for Calico generally. If you'd like to try it out, head over to the Calico documentation, which has set up instructions for VPP and all the other data planes. And if you have any questions at any point, don't hesitate to ping us on the Slack channel as well, or you can ask them straight away. Thanks very much for listening and taking the time.