 My name is Nipendra and I am founder of Cloudiga. Before starting Cloudiga, around seven years back, I have worked over a decade in different companies, but primarily with Red Hat though. I have experienced as system administration, support engineering, file system, kernel and perfending engineering. In 2015, I wrote a book on Docker and then published a course on edX for the CNCF on Kubernetes which has been taken by more than 200,000 users across the globe. At Cloudiga, we provide trainings in the space of cloud native and have many clients. Now let's get back to our topic. EPPF at the heart of it is a way to program the kernel dynamically and get insights from it. It is changing the game in the system side the way JavaScript has enabled us to bring everything on the browser. And because of that, many interesting use cases are coming up for this. Even the Windows kernel is going to support the EPPF in some time. Let us now look at brief history about EPPF. So before EPPF, there was BPF which is Berkeley packet filter. As the name suggests, it is used to filter the network packets. In any OS, we have two primarily things. One is user space and the kernel space. In the user space, we have programs like browser, editors and so on. While on the kernel side, we have programs using which we can interact with the devices like network card, disk and so on. Before BPF, when the network packets used to come to our system, we used to send them to the user space for filtering, which is very expensive affair. But with BPF, we have enabled that functionality in the kernel by creating a virtual machine inside the kernel itself. So when the packets come at the network layer, we could easily filter them out. And that made things very faster. And I believe you would have used the software like TCP dump which used this BPF and helped us debug the network issues. Let us now look at EPPF, which is extended Berkeley packet filter. But it is not meant for just the network anymore. Though the name is a bit confusing, but that's how it is. With EPPF, we have implemented journal event processing and filtering mechanism. We have a global data store as well, which we call them as maps to store the state between the events and share it with the user space as well. The core of EPPF is lives in enhancing or extending the capabilities of the Linux kernel without changing the kernel code or loading a module. And this makes things very simpler. So if you have been part of the Linux kernel community, you know that to bring up a Linux feature in the kernel may take up to years, which is just too much. And by the time the feature has arrived, we may have moved on as well. But by dynamically programming the kernel with EPPF, it changes the game significantly. And we can now come up with a number of use cases for that. And we will look them in few minutes. We can attach EPPF to different programs like any Linux kernel, anything in the network stack, any user space program and so on. So we can attach this program to any of these events. And whenever those events happen, we can perform something. There are many use cases for EPPF now. Now if you look at in the clouded world, we will talk about Kubernetes, which runs multiple containers. And these containers in most cases are just programs. And if we can attach the EPPF at the kernel level, we can actually look at what's happening in every container and so on. So rather than putting something at per container level like a sidecar, we would filter them out or we can inspect them at the kernel level. So things would become very simple. Now there's one more use case in the networking space as well. So if you look at in the Kubernetes ecosystem, we communicate with the pods throughout the Kubernetes cluster. And generally we do it with the help of Kube Proxy. So with Kube Proxy, we create these firewall rules and that help us communicate with different pods. If we have a lot of pods, then that can be significantly slow because of the way IP tables would work. But again, if we have a lot of pods. But on a similar case, if we move to the EPPF-based C&I plugins like Cilium, things are very fast because we are not going anywhere in the IP tables route. We just go from the kernel layer itself and that makes things very fast. EPPF has been well tested for some of the good balancing projects like Catron from Facebook, Unimog from Cloudflare. And there is an active word going on to implement service mess with EPPF. So good times ahead. As with EPPF, we can look at everything what is happening inside our system. There are very good use cases for both security and observability as well. In the security terms, we can have the tooling built around networking and the runtime security as well. Falco, Tracy and other policies are some of the example of security things there. Similarly for observability, we have different tools like Pixie and so on using which we can observe in the system what's happening through and throughout. Before we jump into the architecture of EPPF, let us look at some very basic examples and see what are possible with just single liners. You can also trigger the lab and then perform the hands-on lab along with me. So now here, I'm going to first install a tool called BPF Trace which is a highly important language for EPPF programs. So let's install that first. Once those will get installed, we are going to run a very simple program to trace all the system calls and then we print them by counts. So our BPF Trace has been installed. Let us now look at our first example in which we are going to get system call counts by the programs. So if I run this script, it is going to collect the system calls called by every program. Now if I just press control C, you can see that there have been few programs which are running on the system and they have called different number of system calls like the node program has called 41 system calls and so on. Now with the next example, we are going to list down all the best commands which have run throughout the system. So I run this particular program and let's say if I open up a new terminal and run few commands, let's say I run few commands like this. Now if I go back, I can see that these programs are listed here. So we have run the date and the calcum on and they're listed here. So again, a very powerful example. If you want to kind of look at what commands people are running across the system. Let me do a control C here. Now in the next example, we are going to trace new processes via the exec calls. Let me run this program here. So the program is now running. Let us now go in, let's say do few more things here. Let's say if we run date command, do a bash here and so on. Let's go back here and check. Now we can see here what are the new processes we have called here and these are being listed here. Now in the next program, I want to trace all the active TCP connections. So I'm just going to again just run a very simple script. And this particular script is now running. Let us now go and try to make some connections. So let's say if we do a curl on cloud with a website, let me just add the minus L here. Yeah, something has come up. If I kind of go back here, you can see here, now it is listing all the TCP connections what we are making here. Now on the screen, we can see different BPF trace types, which you can attach at different places in the system. So as you can see, we can attach them with respect to devices, memory, CPU, user space programs and so on. So we can actually put or have these scripts for each individual subsystem what we have here and we can then see what's happening exactly on our system at any point of time. Now we have seen the basic examples. Now let's see how does BPF actually work. So here is a high-level diagram, which is going to explain you how things are happening behind the scene. So we need to load our BPF programs by the BPF bytecode, which we can write manually, but of course writing manually bytecodes is just going to be too much complicated. And that's why we have different tool chain which have been built, using which we can easily write these BPF programs. So there are different tool links. We have seen the example of BPF trace already. Then there is BPF compiler collection we call as BCC. You can even write now the programs in Rust language and so on. So once we have kind of have generated the bytecode, so now once we have the bytecode either by writing it manually or from any one of these tools, we can load that bytecode to our kernel with the BPF system call. And first we hit the verifier, which would verify whether the code which you are loading is safe to run on the kernel or not. If it is not safe, then verifier would fail it and not run it. Post verification we are going to use just in type compilation step to convert our instructions to the respective architecture what we have. And once we have done that, we are going to attach the program to different events what we have. And those events as I said earlier can be any kernel call, can be any user space programs, can be any trace points or and many more. So once we have attached to any of these events and if those events occur, we are going to do the data collection. And the data collection we are going to do with the help of maps and using this maps we are going to share those stats in the user space which we can visualize or see it in the text or whatever it is. Now there are different kind of maps we can create to collect the state of the events and so on. Now here is a very simple program which we would write with VCC and Python and try to hook it with an event. So whenever that event happens, we get some data out and we'll see that. So again, there are different front ends as I mentioned earlier. So we are going to use the BCC library with the Python program to run a particular example. So only we have just added the front end now. So let's see how this is going to happen. So for that purpose, we are going to first load a few packages to perform those steps. So we'll just load the BPFCC tools and the Linux headers package. Once you have done that, here we have the Python program and as you can see with the Python we are first importing the respective module and then we have this BPF program which we just written in like in the C language here and we are going to load that particular program with BPF call here. So if you look at in this particular program, we are simply saying that whenever this particular function is being called, run the print hello kts and clouded community. Now what we are doing is we are loading this particular BPF program and attaching it to the system call clone. So whenever we are going to fork, we are going to run this function and print out the output like hello kts and the clouded community. So let's try to run this particular program now. So we are now running this program here. It's all there. Now let's go ahead and do some fork. So this is going to kind of spin up few more terminals here. Maybe write, date, some other components here. And now as you can see here as we kind of perform any of the clone functionality by any means in the system, we are getting this particular output on our screen. So with the BPF, we are just bound by our imaginations. With the BPF, we can program the kernel dynamically and to the end user or developer, we're just going to have an API call using which they can program the kernel for their own choice. And that just brings enormous flexibility to the developers to bring up many and many use cases. So in the coming future, we are going to see a lot of use cases coming up with this technology. So I highly recommend you to keep an eye on this technology and see what our use cases are coming here. Thank you.