01 Introduction to Data Plane Programming (Stephen Ibanez)

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
okay great thanks Robert so as you mentioned my name is Steven banyas I'm a PhD student at Stanford University working with Professor Nick McEwan just to give a brief synopsis of my involvement with the p4 community I've been spending a lot of time working closely with some folks at Xilinx in Cambridge to put together a workflow to compile p4 program to the net FPGA for those of you that don't know what the net of PDA is that's okay stay tuned because at the end of the my session I'll give a quick pitch on the P for net FPGA workflow so stay tuned for coming attractions so without further ado let's go ahead and dive into it so for the first 20 minutes or so I want to spend some time explaining just giving a brief introduction to what data plane programming is and providing some motivation so to explain what data plane programming is let me first start off by explaining how network systems are currently built so when you want to build a network system you first start off with your list of requirements and all the features you want to include and then you go and you try to or you go and look at all the available packet processing chips that are out there on the market which all have a datasheet that specifies Ruess roughly in english how they process packets so you go and you read all of those data sheets and you try to understand how they're working and once you do decide on a chip then that defines bottoms-up how the rest of your system will be built so it defines how the driver is written as well as how the control plane running in the switch OS is able to interact with the data plane and the fixed function chip and now of course if you want to go and add a new feature to your network for example add a new protocol then you have to go and change your fixed function chip which can take four years in the best case and after those four years you've probably figured out some hack to get around your initial problem so you don't actually need that new chip that's coming out anymore or if you do need it then you throw a place all of your hardware which is very expensive and can be a huge pain so what p4 and this whole programmable data plane movement are trying to do is it's trying to turn this design philosophy upside down and we do that so what we really want to be able to do is to define at a high level exactly how package should be processed and we do this by writing a p4 program and that p4 program is then compiled onto the p4 programmable devices and in this way we get to let network system designers define exactly which features they want to have in their network without having to let third-party chip vendors make those decisions for them and so to motivate this a little bit more I want to highlight a few more benefits of p4 so of course an obvious benefit is that you can easily add new features but you may also want to remove features that you're not using in order to reduce the complexity in your network because so often Network failures are caused by interactions between protocols that network operators sometimes don't even know they're using and with p4 comes much greater flexibility in terms of allocation of resources to tables you can whereas with fixed function chips those allocation between tables the reallocation of resources between tables and the features are baked in at design time and along with programmable data planes we see much greater visibility into the network as new diagnostic techniques start to arise such as in Ben Network telemetry p4 also brings about a much more software style development process which enables a rapid design cycle which enables fast innovation and you can actually fix data plane bugs in the field so you don't have to go and replace all of your hardware anymore you can just change your p4 program and push that out to your devices additionally since you don't have to go and talk to a third-party chip vendor to ask them to add in your brilliant new ideas into their next version of their trip you get to keep all of your own ideas so that allows you to obtain a competitive advantage another great thing about before is that it can be compiled to many different target devices the Tofino is a flexible match action based ASIC that's fully programmable IP for metronome has a p4 and C based framework for programming they're smart Nick and there's also before compilers for software switches such as open V switch and Xilinx has a p4 compiler for FPGAs which as I already mentioned has been integrated into the workflow for programming the net of PGA for him now what can you do with p4 well there's already lots and lots and lots of interesting applications many of these applications have been published in high-profile conferences such as sigcomm Silk Road as a stateful layer for load balancer that's it uses the primitives exposed by p4 there's nd P which is a low latency congestion control algorithm for for data centers and that has a reference implementation p4 as well you can build a fast in network cache for key value stores or as I already mentioned in band network telemetry which is enables unprecedented visibility into your network ID I love what we just didn't have before and you could also implement Paxos if you wanted in your network and the list goes on and on so just some brief history about the language in p4 so it started the ideas around programmable data planes and the name p4 which stands for programming protocol independent packet processors that came about in 2013 and in 2014 the first version of the language p4 14 as it was as it was called came about and that went through a number of different draft versions and in at the end of 2016 p4 16 the first version of first draft specification of p4 16 came about and yeah first draft specification p4 16 came out and that's the version that we're going to be using today so I just want to point out that there's this older version of the language called p4 14 and so if some of you are familiar with people are 14 and not p4 16 that's ok there's a lot of overlap obviously but you'll still be able to learn a lot today yeah so we'll start off with the data plane model of of p4 that's provided by p4 so when we're designing a packet processing system or when we're designing a programming language in general it's very useful to settle on an abstraction that's convenient for that's convenient for expressing the algorithms that we want to implement so p4 itself is based on a high speed packet processing device called Pisa which stands for protocol independent switch architecture so Pisa consists of a programmable parser which is where the user it defines the headers that they'd like to recognize on their order within the packet and then there's the stages of match action processing and this is where the user defines the tables that they want to use in their algorithm and really defines the exact packet processing algorithm that they're trying to express and there's also the D parser so the D parser is responsible for putting the final headers back together to form the final packet so the way that Pisa works is quite straightforward first a packet will come into the programmable parser that programmable parser will rip the headers off of that incoming packet and expose those headers to the subsequent stages of match action processing and as the headers traversed through the match action processing stage each stage of processing will perform you can think of it as a transformation of these headers so the headers can be added or removed or modified or data can be moved between the headers and metadata and perhaps some device state and at the end once the final packets are removed are presented to the d parser the d parser is responsible for putting those final headers back together to form the final packet so parsers and controls these are the main programmable elements of a p4 program so these are the things that you define their functionality and p4 so parsers are implemented as a simple state machine and their job is to extract the headers from the incoming packets and control blocks are used to express a variety of different algorithms that can be expressed as a directed acyclic graph so we use them to implement this one or more stages of match action processing as well as the deep our sir and these parsers and controls you define their functionality you as the p4 programmer defined their functionality and they're built using the various expressions and data types that are provided in the language on the other hand these orange boxes listed here the architecture description and the external libraries these are provided by the vendor of the p4 programmable device so the architecture description is responsible for specifying up some particular configuration of these parsers and match action tables in d parsers so as I just presented it on the previous slide the this this piece of architecture this program this is one particular configuration of programmable parsers and match action pipelines and D parsers and the the vendor also provides this library of externs and these these externs are things that are defined that are not defined in p4 but they're provided by the vendor of a particular architecture present it looks like it's working ok yeah so the externs are things that are not they're not implemented in p4 they're not expressed in p4 their functionality but they're provided by the vendor of the particular of the of the p4 programmable device and these are things that so they provide an interface such that they can be invoked by p4 programs so the p4 programmer can think of them as black boxes and there they can often be specific to a particular p4 programmable device so p4 makes the distinction between a target and an architecture so a target is the embodiment of a specific Hardware implementation you can think of it as a target is as the net of pga platform for instance and then myself and the other developers of the p4 net of pga workflow act as the vendors of that of that target so we define a target we defined an architecture to expose p4 programmability of that target so the architecture provides an interface to program a target via some set of p4 programmable devices such as parsers and controls externs and possibly some fixed components so the way that it works essentially is the p4 community develops and maintains the the p4 language and the library of core components that must always be present and then the the vendors provide the the architecture definition the vendor of the p4 programmable device provided an architecture definition to expose programmability to the p4 programmer as well as a library of externs and so a target can support multiple architectures and different targets may in fact support the same architecture which enables portability of those p4 grams so let's walk through the steps of programming a P for target so you as the P for program are start off with the elements that are provided by the vendor so that's the the target the packet processing target an architecture model to expose P for programmability of that target as well as the P for compiler so you write your P for program to implement all the P for programmable elements that are used in that architecture that is all the parsers and all the control blocks and then you run your P for program through the vendors P for compiler and that produces a target specific configuration binary that's used to tell the target how it should process packets in the data plane so it includes the description of your tables and your X turns and then you as the user also provide the implementation of the control plane and the control plane and the data plane are able to interact with this runtime mechanism that can add and remove table entries it can manipulate the X turns as well and perhaps send and receive control or packets between the with the control with the data plane so in the next session we'll talk a lot about this runtime mechanism so we'll we'll leave it at that for now so now we're gonna start walking through the labs so before we start I just want to make sure everyone has their VM in and installed for those of you that walked in late look for an instructor with USB sticks they they have the VM image so you can download it and once you have your VM image make sure it's up to date so just CD into the tutorials directory and then do a git pull so the reason we're providing these VMs is because we've installed we've pre-installed a number of dependencies which include the BMV to software switch the p4 c reference compiler as well as many nice we'll build a network of our of our p4 switches and then test it out in mini net so each directory contain each exercise directory or each exercise in a different directory and each of those directories contains a make file that is that just compile your p4 program and launches a mininet network with your peers on it and populates the table entries each of the directories also has a send send PI and receive dot hi which is very useful for sending packets so she's a very simple Python client and server that we'll use to send packets between the different hosts in the mignonette network and so each of the exercises has some starter code so look read the starter code look for the to-do comments and that describes the functionality that you'll need to implement so it complete the exercise so this is the the view on model architecture so this is the architecture that we'll be using today for our assignments it's implemented on top of the VM v2 simple switch target it consists of a programmable parser checksum verification and grassman attraction processing block there's a traffic manager so the traffic manager is not programmable in v4 but it performs the role of scheduling packets between the input ports and the output ports and perhaps replicating packets as well and then there's the checksum update and egress match action processing pipeline and a departure so along with the architecture description of the v1 model is also a description of the standard metadata so this is something that's defined in the file that describes the target architecture I just want to highlight a few of the most common Lilly commonly used fields of this of the standard metadata so the ingress port is set by the the view and architecture before the packet arrives at the programmable parser and indicates the port on which the packet arrived the egress spec field is set within the ingress pipeline and indicates the it tells the traffic manager which port that packet should be sent to and then there's the egress port so the egress port is read within the egress pipeline of the view on architecture and it indicates the port that the packet is departing from so here's a template of a typical p4 program that's written for the v1 architecture at the top of the file we include core p4 so this is defines a number of common types that are used in all people our program so all p4 program should include core p4 and then we also include v1 model d4 so v1 modeled up before defines the v1 architecture and as well as all the externs that you can use when you're writing p4 programs in this architecture and people are programs typically start off by defining the headers that you want to include that you want to use in your p4 program and it builds the headers and metadata structs so these struts are passed from block to block of the architecture as the path as the packet propagates through with the architecture and so we define the functionality of our parser or check some verification block our ingress processing block egress pot processing block checksum update block and D parser and finally at the end of the program we combine all those together and instantiate an instance of the v1 switch and call it main so now let's take a look at the the most basic example of a p4 program that I can think of and I like to call this example the hello world hello world example because it's essentially just the wire that connects port 1 2 part 2 so in this simple extras this simple example the parser doesn't have to do anything it doesn't have to extract any headers the verified check sunblock won't do anything either and when the packet reaches the my ingress control block it checks the it checks the port on which the packet arrives so if it's 1 then it sets the egress spec so it sets the report it tells the traffic manager that this package should be sent to port 2 and similarly if the packet comes in on port 2 then it should be sent to port 1 so all packets are coming on part 2 we sent the port 1 and all that come in on port 1 will be sent to port 2 and the rest of the blocks don't have to do anything and at the end of the pipeline or at the end of the program we instantiate an instance of the switch called main so with this p4 program it the routing between port 1 and port 2 is hard-coded and we can't we can't change it after the p4 program has been compiled and pushed out so let's see how we can make this a little bit more flexible so this design achieves the exact same functionality is what we just saw but instead of using that single if-elsif statement in the ingress control logic it defines a single table called forward and that forward table matches based on the ingress port so that's the same feel that we were reading previously so it matches based on English port and the actions that this table can invoke are called set egress spec as well as no action and so the table entries will specify different value different value or it'll specify which action the should be invoked based on four different values of the key so different values of the ingress port so this these table entries say that if a packet comes in and the ingress part is one then invoke the set egress spec action and call that and pass the parameter to to that action so the set egress spec action is defined here we pass in the port so this achieves the exact same functionality and by defining our our P for program in this way we achieve a more flexible design because now these table entries can be added and removed by the control plane so we have dynamic routing between that between the between the ports so for the rest of this exercise for the rest of this tutorial session will focus our attention on trying to implement a basic ipv4 router and we'll use this example to introduce some of the basic concepts of p4 as we go along so our basic our basic IP router will simply parse the ethernet header Ethernet and ipv4 headers perform a longest prefix match on the destination ipv4 address update the source and destination MAC addresses decrement the TTL set the egress port and finally D parse the headers back into the final packet so we've written some starter code for you it's in the basic p4 file so the basic directory so and this is the simple topology that we'll set up in mini net it's just a single trying triangle topology with one host attached to each switch so for this exercise we'll try to send the packet from 10011 to 10.22 so from host 1 to house 2 so before we dive into the p4 programming I just want to point out some of the basic the types that that are commonly used in p4 so an unsigned integer is called a bit string and it specifies length by specifying the end parameter signed integers are called are called it's so with bitstrings you can perform a number of different operations such as addition subtraction concatenation and so forth and support a lot of the same operation some but not all of the same operations p4 also supports the notion of a variable length bit string and this is four parameters or this is four protocols who have to have fields whose width is only known at runtime for example ipv4 options and header types are an ordered collection of members whose members may be one of the types that we we've just discussed headers are byte aligned and they can be valid or invalid so they have an implicit validity bit associated with them and P for program can explicitly manipulate the the validity bit by using the is valid set valid and set invalid methods for the header so here on the Left we show what the ethernet header and ipv4 header might look like when we define it and note that you can use the type def statement to make your p4 program more readable so some other useful types there's the struct so if structs are are very useful and we already saw a use case of this when we showed the standard metadata for the view and architecture so structs are an unordered collection of members with no particular alignment and restrictions so there's three struts that we'll be using to build our IP router or three trucks that are commonly used for all p4 programs that target the VGO in architecture that's the standard metadata there's metadata which is where you as the user can define your own metadata fields and this will be passed along with a packet as it propagates from block to block of the architecture and then there's the header struct so these are the headers of the packet that are also passed along with the packet so a header stack is another useful another useful type that's used useful for protocols like MPLS we have multiple headers of the same type stacked on top of each other so it's essentially treated as an array of headers and a header Union is one of is an alternative of one of several different types of headers for example you might want to declare a header Union consisting of an ipv4 header and an ipv6 header if you expect all packets that pass through your switch to only to contain one and ever both of these so let's talk about parsers parsers are their functions that not input packets to headers and metadata so implemented as a state machine they have three predefined States there's the start state the accept state and the reject state so it's up to the architecture to define what should happen upon reaching the reject state for example the packet might be dropped or it could set in there I set some error metadata bit that can be matched on in subsequent match action processing and the parser can have other states as well in fact it's quite common for a piece or a programmer to define a one state for each type of header that the path that the parser should extract so each state actually in each state the parser will execute zero or more statements and then transition to the next state well and we'll see an example of how this works so the parser for the v1 architecture obviously takes in the input packet and produces this this header struck so it fills out the headers and the header struct the there's also the user metadata and the standard metadata that passed through this parser and can be used if desired in your p4 program so at the left on the top we're showing the packet in declaration in defined in court before and it has a number of different methods associated with it that are very useful for implementing the parser for today we're just will just focus on using the most basic most basic extract method which allows you to extract a fixed-size header from the from the incoming packet so at the bottom we show what an example parser might look like it's a this is a very simple just single state parser so as I mentioned parse was always start in the start state and then in this case it's extracting the ethernet header from the packet and then transitions to accept state so it once it hits the accept state then the parser is done so to implement more complicated parsers we'll often want to use the Select statement and this is used to branch to different states from a particular state so the Select statement has a structure that's very similar to the case statement in C or Java but it doesn't have the fall-through behavior me that we don't need to use break statements so in parsers it's often they often want to branch the different states based on some of the bits that were just parsed from the packet so for example here on the Left we show in the parsed Ethernet state after extracting Ethernet header we want to either branch to the parse ipv4 state or the accept state based on the value of the ether type field so I was going to do a coding break but since I'll have to transition lap stops for that I'll save the coding for the end and then we'll do that all together at the end so with P for 16 let's yeah let's talk about controls now so controls are the other P for programmable elements in an architecture so they're very similar to C functions but they don't have loops and controls you can declare your variables you can create your tables instantiate X turns etc and the this is where use the function the functionality of the control statement so the control flow of the control blocks is specified within the apply statement so when I'm reading control control blocks I'd like to start with the apply statement and so with control blocks we can express all sorts of processing that's expressible as a directed acyclic graph for example match action processing or d parsers or additional forms of packet processing for example updating updating checksums so the interfaces between a particular control block and the other blocks in architecture are governed by user and architecture defined types which typically headers and metadata so here we see we see an example of a control block is very simple all it does is swap the source and destination MAC addresses and then send the packet back out the same port on which it arrived so we declare a 48-bit variable called temp and then temp stores the value of the destination Ethernet destination address as the swapping is taking place after the swapping is done we set the egress spec yeah we set the egress back to the ingress port so hence the name reflector and we could also implement the reflector by defining a simple action called swap Mac and then invoking this action directly from the apply statement similar to how you might invoke a/c function so actions they can be declared inside a particular control or they can be declared globally if you want to reuse them in different in different control blocks and since we're since we're invoking this this action directly from the apply statement each of the action parameters must specify explicitly both the type and the direction and within actions you can declare variables as we're doing here or you can use many different standard arithmetic and logical operators such as the ones shown here so tables tables are really the fundamental unit of a match action pipeline and they specify what data to match on as well as the type of match to be performed table a table definition will also specify a list of all possible actions that can be invoked by this table and they may option a table definition may optionally specify a number of different edition 'el table properties such as the size so how many entries the table should be allocated to contain a default action that should be invoked if no match is found within the within the entries as well as perhaps some static entries so each table contains one or more entries each of those entries specifies a specific key to match on and a single action to invoke if if a packet matches that specified key as well as any action data to provide to the action as input parameters when when it is invoked so yeah let's walk through the steps of performing match action processing so as I mentioned each table consists of one or more entries and that take those tables specify the key the action ID in the action data these entries can be added or removed from the control plane each of the each tables also specifies a default action ID and default default action data and so when the packet comes in its the table will extract the specified bits from the input headers and metadata to concoct and to perform to create the key and then attempt to look up that key within the table entries so if a match is found within one of the entry that the action ID and data are read out of the corresponding entry and if a match is not found then the default action ID and data are used so both of these outputs are sent into the multiplexer sent into a multiplexer which chooses one of these based on whether or not it was found in the table so the selected action ID in action data are sent to the action execution unit so the action execution unit can it can use two different types of parameters two different types of input parameters so there's the data the action data that's stored in the table entries itself but actions can also operate on the headers and metadata so those are passed along to the action execution unit as well and your action code will update the the headers and meta data as you've defined in your in your action to do so so to build our ipv4 router we'll need to define a table so we'll need to define a routing table so in this particular routing table we see the keys are the destination destination IP addresses and when we specify a prefix length so in this particular example if a packet comes in with destination IP address of 10 not ODOT 1.1 then it will invoke the ipv4 forward action and provide us input to that action the destination address and port number shown here similarly if a packet comes in with a destination IP address of $10 1.2 then it will be dropped so I just want to take a moment to highlight the distinction between the data plane and the control plane so the data plane which is described in p4 defines the format of the table so it's the keys the keys that you're matching on the actions that can be invoked the action data and it performs the actual lookup and executes the chosen action the control plane on the other hand is responsible for populating the table with entries so there can be many different control mechanisms for performing for adding and removing table entries but for example based on network operators default or manual configuration or automatic discovery or or routing protocol calculations but really both of these planes have to work together to make IP routing work properly so here's what that routing table that we just described would look like in p4 so as I mentioned the key is that is the ipv4 destination address and we specify a match type of LP M or it stands for longest prefix match and the possible actions that can be invoked are ipv4 forward drop or no action and we specify that the table should be allocated with enough room for 1,024 entries and default action should be no action so when you define your table when you specify the your table implementation you specify a particular match type in tables can have different match types core dot P for defines three three types that must always be supported by different architectures and these are the exact match ternary match and longest prefix match and you can also are different architectures can also specify additional match types in addition to these three standard ones for example the the view one model defines the range and the selector type as well so let's talk about actions so we already you already saw that actions can be invoked directly from the apply statement and based on the discussion we just had about tables you're probably already aware that tables invoke actions as well and so as a result actions have two different types of parameters that can be that correspond to these two different ways of being invoked so directional parameters are those that are provided by the data plane so these are the headers and metadata that come along with the packet and then there's Direction list parameters which are those that are provided from the control plane so these are the things that are stored within the table entries itself and so actions that are called directly only use directional parameters hence the those are provided by the data plane and actions that are used in tables typically will use directionless parameters but may also use directional parameters sometimes as well so after we define what our table should look like we have to apply it within our we have to apply it within our control logic and we do that by invoking the tables apply method as shown here it's pretty straightforward and so next the next thing to cover is the D parser so the D parser is responsible for assembling these headers back into the final packet and here at the left on the top we're showing the definition of the packet out extern from core dock p4 and this has a method called emit and this emit method can be used to insert a particular header back into the packet and it will only insert that header into the packet if it is valid and so remember I I said headers have an implicit validity bit associated with it so as the packet is parsed that parser will set will set the packets validity bit but you can also explicitly unset the headers validity bit within your p4 program if you'd like as well okay so I'll walk through this what's going to happen under the hood when you type make so when you type make it'll it'll compile your p4 program launch a mini net apology and set everything up so when you type make each of the switches is running an instance of this simple switch program and you write so you write your P for Earth so the simple switch program as I said there's a port interface which connects to the virtual interfaces in the Linux kernel and then there's a parser the ingress pipeline the traffic manager the egress pipeline the deep and deep parser and then goes back to the port interface so you write your p4 program and you run it through the compiler which produces this JSON file this JSON file is then loaded into the simple switch program and you can also attach a simple command-line interface to each switch so each switch is running on a different port when you run make it'll tell you which port this each switch is running on and you can connect to that port and this is useful for like reading the table entries and adding and removing table entries and just generally debugging as you're going along to so we set up a bunch of virtual interfaces and each each switch is connected to some set of virtual interfaces and we can send packets through the Linux kernel to the different switch between the different switches with some packet generator and then receive the packets with some pack packets in the fur like Wireshark or or snap a sniff function so each switch will also generate some set of logs which is very useful for debugging so the logs that are produced will be in the slash temp directory feel free to check that out if you get stuck and you want to figure out what's going wrong in your p4 program so to compile the program you start off with the your test p4 and you compile and produce your JSON file so this is the command to to do that but this was done in the make files you don't actually have to do this I'm just walking through the steps of what the make file does so the second step is to set up the virtual the virtual interfaces and so we create pairs of virtual interfaces and connect them together and we have to do some some things to make sure that the Linux kernel doesn't do anything unexpected as we're testing out for example we have to disable the TCP offload engine and we have to disable ipv6 and to start and the make file also start up all the models so we can pass it which ports which virtual interfaces to connect to and we can say whether or not we want to generate the logs and whether or not we want to produce the pcap files so we can sniff on all the interfaces and you can that allows you to see how the switches are processing packets about the inputs and the outputs yeah so to start the the command-line interfaces there's a commands a simple switch CLI you can also pass it a port number as an option remember I said each switch is running on a different port so you just run simple switch CLI to startup that and connect to a particular switch and once you do connect to that the command-line interface and you connect to a particular switch you can type help and see all the list of all the available commands that can be that can be used to debug and figure out what's going on in your table you can show all the tables that are in the switch dump table entries add to remove table entries and so forth so for these exercises we'll be using mostly SCAF II so pythons copy is a very useful packet generation packet sniffing tool it's very flexible but you could use other things as well you can use the built-in linux utilities or Wireshark to do packet sniffing for example ok so I'm gonna switch laptops now and we're gonna go through the implementation of the basic IP router yeah so let's let's go ahead and walk through the the basic P for exercise so implementing our basic router together so we're in the this is the directory here we're in the basic directory so P 42 2017 fall exercises basic so if we open up the basic P 4 file we see so this file follows the same general structure as the hello world example that we saw earlier so at the top we define we include kora p4 and v1 model as we did before and we define the type type ipv4 which is the hexa de hexadecimal value 8 0 0 corresponds to that and that will be used using that in the parser to implement our parser so that's the ether type of the ipv4 so we've already defined the headers so the ethernet header and the ipv4 header for you in the starter code it's similar to how ir or this is exactly the same as how i showed you in the slides before we've built the header struct already so we've included instances of those headers within the header struct so now we have to implement the the parser so let's start with this as I said before the way that I like to do it is I define a different state for each type of header that's being invoked so we want to parse Ethernet parse Ethernet yeah so as I said before I like to define a different state for each type of header that is being parsed so we have the start state the parts Ethernet state and then also define the parse ipv4 state parse ipv4 so our packets will always start with the they'll always start with the ethernet header so let's transition to the Parsee Ethernet state from the start state so transition to parse Ethernet okay so yeah from the start state we're going to transition to the parse Ethernet State and then within the parts Ethernet state we will need to extract the ethernet header so we do that by invoking the packet in so packet is is an instance of the packet in extern so it has a extract method associated with it so we will do packet extract and we will extract the ethernet header header dthe ernet okay so after we use it extracted the ethernet header we're gonna want to examine the ethernet ether type field so the ether type field and so we'll use the we'll want to branch to either the IP v parse ipv4 state or the accept state based on the value of this ether type field so to do that we will transition select and we will select on the Ethernet headers ether type feel so Ethernet dot ether type okay great and so if the ether type field is the type IP v4 that we've defined above so type ipv4 ipv4 then we want to transition to the parse ipv4 State so parse ipv4 otherwise the default catch-all will be to transition to the accept state meaning we're done parsing so default accept so if the ether type is not type ipv4 then we will just transition to the accept state and so now we have to implement the parse ipv4 state so in this state we're gonna want to extract the parse we're gonna want to extract the ipv4 header so just like we extract the ethernet header we will do packet dot extract and it'll be header dot i pv 4 so you can think of parsers as as if there's like a cursor that's it starts at the beginning of the packet and it moves forward it can only move in one direction only moves forward and the extract method will look at the next bits of the packet and fill out the head of the header Specter you pass to it with the next bits of the packet corresponding to the size of the header and so after we has extracted the the ipv4 header then we're just going to transition to accept because we're done transition to accept ok so that completes the basic implementation of our ipv4 router and so now let's take a look at the other blocks that we have to do we won't do anything with the verified checksum just for sake of simplicity and we'll have to finish the implementation of the ingress processing pipeline the egress pipeline won't have to do anything so our egress control block will be empty and then there's a computer check sun block so remember our ipv4 adder will update the TTL it will decrement the TTL so we're going to need to recompute the ipv4 checksum and to do that there's this very convenient extern defined in v1 model p4 which is included at the top of this file and it's called update checksum and it's it's pretty straightforward it'll you pass it the ipv4 header fields and you specify which field should be updated so we're passing it the header checksum field and you specify the hash algorithm to to use and there's different hash algorithms that are defined in v1 model dot p4 so we're passing in this C some 16 and this this external update the will update the header the ipv4 header checksum if the header is valid and if the header is not valid ie a packet comes in that doesn't have an ipv4 header then it won't do anything and we have to implement the D parser so let's do that really quick because it's pretty easy so we want to use the the so packet out now it was packet in in the parser and now it's of type packet out so the packet out type has a method called emit associated with it so to emit the headers we just do packet emit and the header type so header dthe ernet yeah header dot Youth in it okay and we want to admit the packets in the right order so the order definitely matters here so the next after the ethernet header we want to emit the ipv4 header packet don't emit had heard ipv4 okay so that that's the full implementation of the D parser and remember I said the emit method will only insert header into the packet if it's valid so if a packet comes in that doesn't have an Ethernet or doesn't have well it'll have an Ethernet because we're extracting it immediately without checking anything but if a packet comes in that doesn't have an ipv4 header then the packet then the ipv4 header won't be valid and hence the omit method won't insert it into the packet so let's look at the ingress control logics this is the other thing that we have to update so let's look at the starter code that's provided so as I said I like to read the I like to the way I like to read control blocks is by starting from the apply statement so because I this is where the control logon logic is actually defined so we see that it in it applies one table called ipv4 LPM and that table is defined just above here so this is the exact same table that I showed you in the slides before it's matches based on the destination IP address and the match type is LPM which stands for longest prefix match just like we want and the actions that can be invoked are ipv4 forward drop and no action size is 1,024 entries and default action is no action and so no action is defined in court P for just does nothing as you can imagine drop is defined above just right here it invokes this extern called mark to drop which is also defined in v1 model p4 and so the only thing we have to do is to complete the implementation of the ipv4 forward action so this this action needs to do a number of different things the first thing that it needs to do is it needs to do routing or it needs to set the egress spec so this action will be invoked by the table and the table will specify its particular destination IP addresses and provide to this action the port number that the package should go to and so we need to set the standard metadata dot egress spec so this is the field that we set to tell the traffic manager which port to send the packet to okay so we special we've set the egress spec field and now we need to move the packets current destination MAC address to the packets source MAC address so we'll update the header dot Ethernet dot source address to be the header Ethernet dot destination address okay and then we need to we need to make the package destination MAC address to be the MAC address that's provided when this action is invoked right here so this is also something that's stored within the table entries so to do that we just do header dot Ethernet the destination address and that's equal to the provided destination address okay and remember the last thing that we have to do to complete our eyes okay yeah so I'll take a little second to pause does anyone have any questions about what we've done so far great everything is super clear and everything is really easy oh there's one question so no the egress the II respect is what is the field that the traffic manager looks at to figure out which port it should schedule the packet to the egress port field is read within the egress pipeline so that's that's that can only be read within the egress pipeline it says the port that the packet is actually departing from so that's like a you can't you can't set that in the ingress port field or ingress pipeline so let's decrement our TTL so - so that header dot ipv4 dot TTL is equal to header dot i pv 4-1 okay so that oops ipv4 dot TTL yeah so that decrements the TTL field and so at this point we've completed the implementation of our basic IP router so let's check and see if it compiles oops that would no compiled okay so let's check and see if it compiles we can do that by typing make build great - didn't make any typos any other typos okay so now let's we can we type make run or just make that'll do both build and make run but if you type make run then that will launch them it it'll launch the mini net apology with your BMV two switches that are running your p4 program and then we have this nice mini net command line and we can start up - we can start up an extern a terminal on host 1 and host 2 X term h1 and h2 great and so there are there's a senpai and received a pie so on host:2 we will run the received a pie function this is just our really simple Python server and it's just sniffing packets and it'll print any packets that arrive and so on host 1 we want to send we want to try to send to host 2 and the way that this utility works is you specify the destination IP address so this will set the destination IP address in the packet we're sending so the IP address of host 2 is 10 oh 2.2 and we want to spend and then we also specify a message so we'll say the p4 is cool because you can't deny it ok cool so it looks like it it was it arrived correctly it's an Ethernet header and then the IP header and let's look at see if the TTL was decremented so before we sent it it was 64 and when it arrives it was 62 because remember it's passing through two switches in this simple triangle topology so it looks like it's working properly and the messages receive that's great cool so things are working properly so the next thing to do will be to implement the the basic or so there's the next exercises basic tunneling I'm wondering how do you have the slides on here already Robert or no where's Robert no ok I'll I think I'll have to switch laptops again but take a look at the basic tunneling exercise the readme is in the take a look at the readme that's in the exercise and once I get this setup set up again then I will I will explain it again but for the next let's take the next like 15 minutes to for you guys to like work on that and then at the end we'll come through and we'll implement it again and walk through the implementation of our basic IP router or basic tunneling exercise ok so so I just want to like go through the basic tunneling exercise like as far as what you're supposed to do so in this exercise we're building directly on top of the ipv4 router and we want to define a new type called my tunnel which is used to encapsulate the IP packets this is my tunnel header will contain two fields the proto ID which just specifies the type of packet being capsulated as well as the destination ID so that's the destination of the host that we're trying to send to so if a tunnel packet that is a packet with this month this my tunnel header comes into the switch then we want the switch to to forward with based on the destination ID field specified in the my tunnel header and not the ipv4 router not the ipv4 destination address so the list of to do's the list of - duze for this assignment well the first and last on this list have already been implemented for you in the starter code so we've already defined the the type the new the new header type called my tunnel and added it to the header struct so we'll need to update the parser and we'll need to define a new action called my tunnel forward and new a table called my tunnel exact and we'll need to update the control flow in the my ingress control block and we'll need to update the D parser and then we've already provided the the the rules for you the table entries for you and I'll show you where the file is I just realized I forgot to show you the table entries when we went through the basic router but I will make sure to do that in this time and the so this is the basic topology it's the same as we had before this diagram also shows the port numbers for the switches so we can understand how how they take what the table entries are supposed to supposed to be so let's go ahead and walk through this ok so wherein we went from the basic directory to the basic tunnel so the starter code is in the file called basic tunnel so the starter code is basically just the solution for the basic ipv4 router so this file includes core top before again we defined this new this new type called my tunnel type so this the ether type that corresponds or that will use to determine whether or not the packet has an my tunnel header and then there's the same ipv4 type as well oh we need to change the what was it bheegi bheegi : what dark dar k okay okay great thanks again okay so we've defined the the new the new header type already my tunnel existed the proto ID in the destination ID field that i said already and then there's yes so we and then we added that the the my tunnel header to the header struck as well so we will start by updating the parser logic so for the parser we're going to want to define a new state to actually parse our our my tunnel header so let's do that so the state will call it parse my tunnel parse my tunnel okay and in this state we're gonna want to extract the mic tunnel header from the packet so let's do that so it's the same as how we extracted the how we extracted the ethernet header and the ipv4 header so we'll do a packet dot extract and it's header dot my tunnel okay and then after we've parsed the my tunnel header first does does this does this make sense to everyone what we've done so far we'll still need to update the parts Ethernet logic to actually transition to the parse my channel state but for now we're just focusing on the on the implementation of the my parse my tunnel state so remember the the my tunnel header contains a field called proto ID and that proto ID field indicates what type of packet is encapsulated within the my tunnel header and so if the the proto ID field is equal to the type IP v4 that we've defined above then we want to transition to the parse ipv4 state and so to do this just like we have done in the past to transition between two different states we use the Select statement and so we want to transition select and we're selecting based on the the my tunnel headers proto ID field so that's header dot my tunnel dot proto ID okay so now we're looking at the proto ID field and we want to if it so it see if it's equal to type ipv4 so it's very similar it's take a look at the Ethernet header so it's it's gonna look exactly like this actually like if in this case in the parts Ethernet header if the ether type was equal to type ipv4 then we want to transition to the parse ipv4 state and in the parse my tunnel state if the my tunnels proto ID field is equal to this value then we're gonna want to transition to the parse ipv4 State so let's just type that type IP v4 and we're gonna want to transition to the parse ipv4 State and the default so we'll only look at encapsulating ipv4 packets for now so that's the only type so if it's anything else if the proto I do you feel does anything else then we want to terminate the parser we're gonna be done so well the default will be to change this into accept okay so now we have to update the the parse we're gonna we're gonna want to update the the parse Ethernet State so well so if a packet comes in that's not encapsulated that is it doesn't have a my tunnel header then we want it to to parse the ipv4 header so as it is now we this is correct but we're gonna want to add in another condition so there's two different types that the ethertype can be that can either be type ipv4 or it can be type my tunnel which is that constant we defined at the top of this file so type my tunnel and we're gonna want to transition to the my tunnel state parse my tunnel so now we're checking two conditions for the parts for the ether type so if it's my tunnel then we transition to my tunnel and otherwise to parse ipv4 so does this make sense to everyone are there any any questions so far okay great so this is the full implementation of our of our updated of our updated parser to parse this my tunnel header or encapsulated in normal IP packets so now let's let's take a look at the other things that we will have to do so we won't again do anything with the my verified checksum block we'll have to update the the logic in the ingress pipeline we'll do that at the end and we won't the egress pipe line doesn't have to do anything either so we'll leave that blank the compute checksum block isn't doing anything or is if it is doing something it's doing the same thing that we just did in the previous exercise and we don't have to change it at all because we don't have to change like the position that the packet is or that the the X turn is updating because we just pass it the ipv4 header checksum field and so it updates correctly and so let's let's do the parser so the parser it's gonna look very similar remember I said that the omit method only will insert a packet into the parser or into the packet if it's valid so we don't have to do any extra checks of validity for the header fields or anything we can just make this look exactly like the other ones so we're gonna want to omit the header my tunnel so in this case it'll emit it'll met the headers in this order so if a packet comes in that's tunneled it'll limit the ethernet header then my tunnel header then the ipv4 header and if a packet comes in that's not tunneled then the my tunnel header won't be marked as valid so that hence the omit method won't actually insert it into the packet and it'll be exactly like we want the Ethernet header than the ipv4 header so this is this is it for the deep arcing logic are there any questions about this if not then we'll go on to implement or finish the implementation of our ingress logic okay yeah so if you wanted to strip yeah if you didn't want to insert the packets into the headers into the packet then you just don't admit it yeah yeah exactly if you wanted to omit ipv4 then Ethernet for some reason then you could do it you swap the order so the my ingress control logic is exactly how it was in the previous assignment so nothing has changed here so we're we're gonna want to define a new table called my tunnel exact which performs an exact match based on the my tunnel based on the my channel destination address destination ID field so let's just make a copy of let's just make a copy of this table a p.m. table so for those that are using them if you want to make a copy you can highlight it type V inter visual mode and then you can type Y for yank and then you can paste it so let's update the implementation of this of this table so we're gonna call it my tunnel exact my tunnel exact okay and the the key for this table will be the my tunnel headers destination ID field so let's update this header dot my tunnel the DST ID and we want to do an exact match so we specify the type of exact and then the actions that can be invoked by this table we don't want to invoke the ipv4 forward action we're gonna invoke a new action that's called my tunnel forward my tunnel forward and the other actions are the same as the previous table so you also the table could also invoke the drop method or the note or no action so this is it this table decoration makes sense to everyone everyone's happy with this so far great so we have to define this new action the action is called my tunnel forward the point of this action will be to set the egress spec field appropriately so that the traffic manager knows which port to send the packet to so we'll define the action it's called action my tunnel forward okay and the the input print are the parameters that will be provided by the that will be provided by the table note that the parameters are directionless and that's because they're invoked by the table if we were to invoke this action directly from the apply statement then we would have had to specify the the direction of the input of the parameter but in this case it's invoked by the table so we don't we its direction this parameter so you grass spec this is a this is a type that is that is defined in in v1 model so the input parameter for this action is the port and all this action has to do is update the update to each respect field so standard metadata the egress spec is equal to the provided port number so this this is the field that'll tell the traffic manager which port to send the packet to so it's very similar to how we were setting the USR it's exactly the same it's how we were spending the are setting the egress spec field in the ipv4 forward action but in this case we don't have to decrement the TTL or anything because it's not part of our routing protocol for my tunnel headers we just want to look at the my tunnel header and then perform forwarding based on that and pretty much completely ignore the ipv4 forward header so now we've defined our new table we've defined our new action the only thing that's left to do is to is to update the control logic so if the ipv4 header is valid and the my tunnel header is not valid then only then do we want to apply the ipv4 for LPM table and perform IP routing so the end the this is the logical and operator operator and p4 and so we want to check if ipv4 header is valid and the mitem header is not valid so and not header dot my tunnel dot is valid okay so so now we're we're we're only performing IP routing if the ipv4 header is valid and the my tunnel header is not valid and we want to forward based on the my tunnel header only if the Mitel header is valid so we can add another if condition in here so if header dot my tunnel dot is valid and so if the my tunnel header is valid then we want to apply the my tunnel exact table that we've just defined so we'll apply that table my tunnel exact dot apply so this will this will apply that table and it'll perform the match based on my tunnel headers destination ID field and the table entries will specify which action to invoke for different values of the destination ID field the table entries are specified in a different a different file I'll show you I'll show you that very soon but so at this point we've completed the implementation of our basic tunnelling example and I just want to check and make sure I did this yes okay I did I did do this okay so we're done with the implement the P for implementation of our basic IP router let's take a look at the table entries so the table or the command-line arguments the command lines to add entries the table are specified in the s1 through s4 t xt file so each switch has a different set of commands to add table entries so let's look at the commands that are used to populate the table entries for switch 1 so the first line sets the default the default action of the ipv4 LPM table to drop this these these first four entries were also specified in the s-1 - commands txt file for the basic IP router but I forgot to show you that but this is the exact same table entries so and the next three lines add add different yeah dad add different entries for different values of the destination IP address so so this says if a packet comes in with destination IP address of 1000 1.1 I P V hoo ipv4 forward action with these parameters so if you're Matt if you go back and look at the p4 description of the of the ipv4 for an action it specifies that there's two in there's two parameters that it takes and that's the destination destination address and the port number and so our tape our my tunnel table is pretty much the exact same forward as format as that so we want to specify the default action should be drop and then we add we have different table entries for different possible values of the my tunnel headers destination ID field so the sides three so if the packet comes in with destination ID field of 1 then we want to send it to port 1 destination ID is 2 then we want to send it to port 2 okay so let's check and see if our if our if our example that we just coded actually compiles to do that we type make build ok great didn't make any typos so now we can run it I'll type make this time just to show you that it does the exact same thing so this compiles the p4 program again and then launches the mini net topology with your BMV 2 switches other described in p4 and we can open up h1 and h2 a terminal on both host 1 and host 2 again just like we did before there's the senpai in the receive pie functions again but these are slightly modified so that they will they can also send tunneled packets so they can also send the packets with a with the my tunnel header and caps electron caps elating an ipv4 header so let's run the receive function on host - this one's pretty much the exact same it just sniffs and we'll print out any packets that are received and then we want to send so let's check and see if just normal IP routing is working make sure we didn't break anything so to do that we specify the destination IP address of the host - which is 10 0 - 2 and we can specify a message again so p4 is cool okay great it looks like IP routing is working the TTL was decremented again and went from 64 to 62 and it reached and it reached the destination host of host 2 so that looks good so now let's try to send a tunneled packet and see if things will work properly so to send a tunneled packet we can use the same utility so remember that it doesn't look at the destination IP address at all so we can use whatever we want for the destination IP address so we'll say 10 dot I don't know 1 2 3 and then we can specify message of p4 is great in all caps P P dollar sign is great p4 is great and then to send a tunneled packet you specify a destination or destination ID and the destination ID of house 2 is 2 so we'll send that and hey it looks like p4 is great arrived so packet arrived and it is indeed a tunneled packet so there's the Ethernet header and my tunnel header and then the IP header and so note that I didn't look at the IP address at all so it wasn't doing IP routing it was actually forwarding based on our our own custom tunneled header so that's that's pretty much the whole exercise at this point one thing before we stop I wanted to point out to you is that in the directory structure for the exercises at the top of every well you'll see that in the exercise directory there's different exercises throughout the day at the top of every the top layer of every subdirectory is a readme file and you can take a look at that readme file and it step-by-step describes sort of what that exercise is supposed to do and also the steps that you need to do to complete the exercise so if you want to follow along and you miss the slides on the on the projector you can just refer to the readme file the other thing to point out which I'm not sure if you do did or not but every directory also has a solution subdirectory if you want to cheat I don't encourage you to cheat but at the same time there is a working solution in the solution subdirectory and you can take a look at that to sort of understand any problems that you may have had if you want to if you want to sort of rapidly try and figure out what's going on okay
Info
Channel: P4 Language Consortium
Views: 5,817
Rating: 4.9354839 out of 5
Keywords:
Id: qxT7DKOIk7Q
Channel Id: undefined
Length: 75min 29sec (4529 seconds)
Published: Wed Nov 29 2017
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.