So the next thing that we will look at is network debugger. So this one we said is static and this one is going to be dynamic, and we'll see what that means. In particular, all of us have used some sort of a debugger, SDB and GDB and things like that. So that gives you a way by which you can set the breakpoints in your program, watch a particular variable in a program, and make assertions about what should be the value and things like that. That's the way you would debug the control flow in a program. They want to use the same idea for a network debugger and it is for live debugging of errant network behavior. So the approach is you are starting with SDN, so everywhere they're starting with SDN. SDN architecture is systematically doing certain things in terms of setting switches and so on. So we can use that same leverage, the same infrastructure for systematically tracking down network bugs. So the idea is to capture and reconstruct the sequence of network events that leads to an errant behavior. So what you're going to do is set network break points just like you do in a symbolic debugger, you set break points, you're going to set network breakpoints, but it is at the level of switches. The level of the switches you can say, here are the filter function that I'm going to set for a particular switch to identify a particular errant behavior. What that'll do is it result in a backtrace generation saying that well, that particular setting is going to affect all of these switches in the particular sequence in the path taken by a packet, and the scale of the flow tables at each switch. That is the way you would identify the errant behavior. So let me give you an example. So for instance, let's say the simplified network topology of nodes and a system A and B are the hosts. So how do you go about setting up a breakpoint? Basically, at a switch, you want to say that I want to observe anytime there is a packet that has a source address A and a destination address B and if it is using TCP as the transport, I want those packets to be flagged as things that I care about. So if I said this at a particular switch here, then it effects all of these other switches which are in the path from A to B. So the observation has to happen in all of the switches whenever these rules are actually observed in the packets that are flowing through the network. So what is going to happen is that as a result of, say, a packet going from here to here. When this packet reaches here, then this rule says, "Oh, it's source address is A and the destination address is B, and the port is 22." Therefore, I'm going to send a notification to this guy which is called a postcard. To the collector I'm going to send a postcard from here saying that I did see this event. Then this packet, let's say flows here and this guy does the same thing. He says, "Oh yes, I do observe. It is the same source address, destination address, and port." So we get another notification from here. These are what are called postcards and the role of the collector is to collect all these postcards. So similarly, when this goes up here, I'm going to get another postcard from here. These postcards are accumulated by this collector and that is what he's giving as backtrace. So for instance, let's say that I'm interested in this packet reaching here, but I never got to this point. So another words, this never happened, the packet never came here. If it never came here, I will not get a postcard from this guy. So later on I can figure out that, there must be something wrong, some network loop here that resulted in this packet not reaching this particular switch. So you can actually build the backtrace and analyze at what point the communication failed. So this is the way you can do network debugging using this tool. So the question is, who sets these rules? So in my application, I know that there is a flow that has been set from A to B. I'm noticing that there is no packet arriving at B and when I set this rule, this rule propagates to all the reachable switches from here. Because for packets from A to flow to B, it has to flow through these intermediate switches to get here. So this rule gets set in all of these things and once it is set all of the switches, then when the application is running, these postcards is telling you, so you're not slowing down the application to a great extent, all you're doing is generating a postcard notification and the collector just gets all of that. Then you can see where it is failing. Several sources of scalability. Now, first of all, the collector, if you have a central collector, and that is managing all the network flows, not for a single application, but all the application. Even with a single application, lots of flows and then all the applications, then it becomes a huge bottleneck. So there are some ways in which you can combat this challenge. Number one, maybe you're not interested in the entire network fabric, but you might say that only this portion of the network that I care about. So you can actually confine the rules to be applied to a set of switches that is there not the entire switch fabric. That's number one. The second thing is, this collector is a central entity. You can paralyze it. There's no reason there should be a central collector, you can paralyze it. One of the things that I should mention is many of the things that I'm pointing out are research tools. So they're not production tools necessarily. So if we want to make it a production tool and you want to make it really scalable there's certain things that you have to do. But there are hooks at least for saying, can I confine the observation of the network to a subset of the switches? That is something that you can do.