WEBVTT 00:00.000 --> 00:21.280 We're going to have Fernando's going to be talking to us about flexible network operations 00:21.280 --> 00:24.760 on network packet fields with NF tables. 00:25.760 --> 00:27.360 All right, hello, everyone. 00:27.360 --> 00:29.760 I'm Fernando, I'm a Linux kind of network engineer, 00:29.760 --> 00:34.760 Susa, and recently I sent a new RFC to net feed 00:34.760 --> 00:38.760 turn NF tables implementing a new NF tables expression, 00:38.760 --> 00:41.760 which is the NFT math expression. 00:41.760 --> 00:44.760 And here we are. 00:44.760 --> 00:48.760 So a little bit of context. 00:48.760 --> 00:51.760 Well, you know, IP tables and if tables a bit 00:51.760 --> 00:53.760 integration, people is moving away. 00:53.760 --> 00:55.760 But there are still some stuff that people can 00:55.760 --> 00:58.760 do in NF tables, thankfully. 00:58.760 --> 01:03.760 So we are trying to reduce that gap in features. 01:03.760 --> 01:07.760 And one of the remaining features was the TTL increase, 01:07.760 --> 01:11.760 the increase of TTL manipulation that is not just a plain set. 01:11.760 --> 01:15.760 So how it works first in IP tables. 01:15.760 --> 01:17.760 So in AP tables, usually you will just use the, 01:17.760 --> 01:20.760 I get those extensions for TTL, 01:20.760 --> 01:23.760 you will call it TTL increase, whatever number, 01:23.760 --> 01:25.760 or TTL decrease. 01:25.760 --> 01:29.760 And the best thing about this is that 01:29.760 --> 01:32.760 well, only works for TTL. 01:32.760 --> 01:36.760 It's not doesn't support any other packet field. 01:36.760 --> 01:40.760 And that's in the IP tables model. 01:40.760 --> 01:43.760 If we wanted to support, for example, 01:43.760 --> 01:47.760 we would like to find a meta mark. 01:47.760 --> 01:51.760 We will need to create a new extension to just handle that. 01:51.760 --> 01:53.760 And therefore, it's a cumbersome, 01:53.760 --> 01:55.760 because the maintainer's boundary of all that code, 01:55.760 --> 01:58.760 and the complicated code will be, 01:58.760 --> 02:00.760 will be to match. 02:00.760 --> 02:06.760 So in essence, we came with the idea to have something flexible. 02:06.760 --> 02:08.760 We really have the payload expression. 02:08.760 --> 02:10.760 We have the meta expression. 02:10.760 --> 02:12.760 So we thought instead of a set, 02:12.760 --> 02:15.760 we could use the code to increase. 02:15.760 --> 02:17.760 And it will, originally, 02:17.760 --> 02:18.760 I will look something like that. 02:18.760 --> 02:21.760 But I might say that this is the user space code, 02:21.760 --> 02:23.760 which is not done yet, 02:23.760 --> 02:26.760 because first we need to get in the kernel code. 02:26.760 --> 02:29.760 But in my mind, the end result, 02:29.760 --> 02:31.760 it would look like something like this. 02:31.760 --> 02:34.760 So you will be able to specify the, 02:34.760 --> 02:37.760 the header, I don't want to modify the protocol, 02:37.760 --> 02:40.760 then the field, and then the operation. 02:40.760 --> 02:42.760 And the code, increase and decrease, 02:42.760 --> 02:44.760 a base report. 02:44.760 --> 02:48.760 But we are open to implement any other mathematical operation 02:48.760 --> 02:49.760 that makes sense, 02:49.760 --> 02:51.760 and we have a new case for them. 02:51.760 --> 02:54.760 And the good thing is that it will be flexible. 02:54.760 --> 02:58.760 So as NF tables has an internal information machine, 02:58.760 --> 03:00.760 and we have the registers, 03:00.760 --> 03:03.760 and also one that we're going to spend a little bit later. 03:03.760 --> 03:06.760 We are able to capture whatever data, 03:06.760 --> 03:09.760 modify that data from the packet, 03:10.760 --> 03:12.760 and insert it into this KB. 03:12.760 --> 03:15.760 So the idea is that this expression, 03:15.760 --> 03:17.760 we could use it everywhere, 03:17.760 --> 03:20.760 so the same implementation could be used for payload, 03:20.760 --> 03:24.760 which could be used for IP, UDP, DCP fields, 03:24.760 --> 03:26.760 whatever protocol actually, 03:26.760 --> 03:28.760 even not only header values, 03:28.760 --> 03:32.760 but you could look into the data if needed. 03:32.760 --> 03:36.760 And then also for other stuff like the meta values, 03:36.760 --> 03:40.760 so the meta mark is the most relevant one here. 03:40.760 --> 03:45.760 And yeah, there is something to the RFC right now. 03:45.760 --> 03:47.760 We are in a B2, 03:47.760 --> 03:50.760 and I have already, I have prepared already a V3, 03:50.760 --> 03:52.760 that I'm glad to send soon, 03:52.760 --> 03:57.760 and I hope I can get this marriage on the next cycle. 03:57.760 --> 03:59.760 So I mentioned it before, 03:59.760 --> 04:01.760 the NF tables register, 04:01.760 --> 04:02.760 so what are they? 04:02.760 --> 04:04.760 In essence, in NF tables, 04:04.760 --> 04:08.760 it's an internal B2 machine to process the rules, 04:08.760 --> 04:12.760 and we have some registers that act like shared memory 04:12.760 --> 04:13.760 within the expressions, 04:13.760 --> 04:15.760 or the NFT context. 04:15.760 --> 04:20.760 So the packet field that can be copied to those registers, 04:20.760 --> 04:23.760 then those registers value can be modified 04:23.760 --> 04:25.760 by any other expression, in this case, for example, 04:25.760 --> 04:27.760 the mathematical expression, 04:27.760 --> 04:29.760 but we have already other expressions I do that, 04:29.760 --> 04:31.760 for example, bitwise, 04:31.760 --> 04:33.760 or byte order expressions. 04:33.760 --> 04:40.760 And that that can be written back into the specific field of the packet. 04:40.760 --> 04:42.760 So for the goal, 04:42.760 --> 04:46.760 we want to reduce the application of goals, 04:46.760 --> 04:49.760 so we plan obviously to use the existing expressions, 04:49.760 --> 04:51.760 like payloads or mate expressions, 04:51.760 --> 04:54.760 because also when you modify a header, 04:54.760 --> 04:56.760 you need to recartulate the checksum, 04:56.760 --> 05:00.760 and that requires some extra operations, 05:00.760 --> 05:02.760 but we already have support for that. 05:02.760 --> 05:06.760 So we can avoid implementing all of these in the mathematical expression, 05:06.760 --> 05:08.760 and we can use the existing support. 05:08.760 --> 05:11.760 And also, we already have the byte order, 05:11.760 --> 05:16.760 especially to be able to change the byte order as needed 05:16.760 --> 05:19.760 when manipulating the data, 05:19.760 --> 05:25.760 depending on what kind of byte order is the data stored in the kernel. 05:25.760 --> 05:30.760 So the byte code generated for use cases, 05:30.760 --> 05:33.760 where we want to increase the TTL. 05:33.760 --> 05:35.760 If we look something like this, 05:35.760 --> 05:37.760 so in essence, what this is saying is, 05:37.760 --> 05:39.760 well, it's defining the table, 05:39.760 --> 05:40.760 it's defining the chain, 05:40.760 --> 05:43.760 and then it says the first rule of the chain, 05:43.760 --> 05:45.760 payload, expression, 05:45.760 --> 05:48.760 it's going to load two bytes, 05:48.760 --> 05:53.760 from the network header plus one byte of offset. 05:53.760 --> 05:55.760 So we get to the TTL field, 05:55.760 --> 05:57.760 and that data, 05:57.760 --> 06:01.760 we are going to store it into the register number one. 06:01.760 --> 06:03.760 And then, over that register, 06:03.760 --> 06:05.760 we are going to apply the math expression, 06:05.760 --> 06:09.760 which is going to say that we want to operate with a field 06:09.760 --> 06:11.760 that is going to be eight leads. 06:11.760 --> 06:14.760 And the reason why we are talking bits of math expression, 06:14.760 --> 06:15.760 and not by it, 06:15.760 --> 06:18.760 as we are doing in the payload, 06:18.760 --> 06:21.760 is that we want to keep it flexible as possible. 06:21.760 --> 06:22.760 So if in the future, 06:22.760 --> 06:26.760 we are going to specify a packet field 06:26.760 --> 06:28.760 that is two bits only, 06:28.760 --> 06:29.760 you are able to do it, 06:29.760 --> 06:31.760 and you don't need to do weird things. 06:31.760 --> 06:32.760 And also, 06:32.760 --> 06:34.760 we need to specify a bit mask, 06:34.760 --> 06:37.760 because depending where the data is placed, 06:37.760 --> 06:40.760 the data in the register could be placed 06:40.760 --> 06:42.760 in the most significant byte, 06:42.760 --> 06:45.760 or the less significant byte of the register. 06:45.760 --> 06:47.760 So we need to specify that. 06:47.760 --> 06:49.760 I must say that all of this, 06:49.760 --> 06:51.760 is usually no handle by the user. 06:51.760 --> 06:54.760 This is handled by the user space tool, 06:54.760 --> 06:57.760 like NFT or faculty or whatever. 06:57.760 --> 07:02.760 So this is kind of more internal than anything, 07:02.760 --> 07:05.760 but currently it's the way we have to prove 07:05.760 --> 07:07.760 the things are working. 07:07.760 --> 07:09.760 And then, what it says, 07:09.760 --> 07:10.760 the register one, 07:10.760 --> 07:11.760 plus one, 07:11.760 --> 07:14.760 and store it again in the register one. 07:14.760 --> 07:15.760 And at the end, 07:15.760 --> 07:17.760 we are going to call the payload right, 07:17.760 --> 07:18.760 this is a expression, 07:18.760 --> 07:21.760 so it's going to write the register one value, 07:21.760 --> 07:22.760 the data, 07:22.760 --> 07:24.760 into which is two bytes, 07:24.760 --> 07:26.760 and then a worker header, 07:26.760 --> 07:30.760 plus eight bytes of a byte, 07:30.760 --> 07:34.760 and then it does some checks and recalculation. 07:34.760 --> 07:37.760 So for the metadata, 07:37.760 --> 07:39.760 for the metadata, 07:39.760 --> 07:41.760 expression is even easier, 07:41.760 --> 07:44.760 because we don't need to do any stuff 07:44.760 --> 07:46.760 related to the checksum, 07:47.760 --> 07:49.760 and it looks like metadata, 07:49.760 --> 07:50.760 load the mark, 07:50.760 --> 07:51.760 into a register, 07:51.760 --> 07:52.760 we operate with a register, 07:52.760 --> 07:55.760 this is a 32 bits field, 07:55.760 --> 07:57.760 we do the same operation increase, 07:57.760 --> 07:59.760 it could be decrease, 07:59.760 --> 08:01.760 and then we set the value with whatever 08:01.760 --> 08:03.760 is stored on the register. 08:03.760 --> 08:07.760 Here we are already handling with all the flows, 08:07.760 --> 08:12.760 so if you are already at the limit of the type, 08:12.760 --> 08:14.760 it's not going to do anything, 08:15.760 --> 08:16.760 and well, 08:16.760 --> 08:18.760 you're not going to have any problem. 08:18.760 --> 08:22.760 All right, 08:22.760 --> 08:23.760 so enough checks, 08:23.760 --> 08:24.760 let's do some demo, 08:24.760 --> 08:25.760 I have prepared a demo, 08:25.760 --> 08:28.760 where I'm going to increase the TTL, 08:28.760 --> 08:30.760 because it's the most common use case, 08:30.760 --> 08:33.760 and I'm going to explain what's happening. 08:33.760 --> 08:38.760 So I have two VMs in the demo, 08:38.760 --> 08:41.760 that are connected to each other directly, 08:41.760 --> 08:43.760 so the packet is being stretched, 08:43.760 --> 08:46.760 without any intermediate point, 08:46.760 --> 08:49.760 the TTL therefore of a ping is not going to be reduced, 08:49.760 --> 08:52.760 when it arrives to the end machine, 08:52.760 --> 08:54.760 because there is no rotating in the middle, 08:54.760 --> 08:57.760 and when we are going to do is to have 08:57.760 --> 08:59.760 one NF table rule, 08:59.760 --> 09:01.760 which is going to set the packet, 09:01.760 --> 09:03.760 if the TTL is 31, 09:03.760 --> 09:05.760 and one that is going to drop the packet, 09:05.760 --> 09:07.760 if the TTL is 30. 09:07.760 --> 09:09.760 So we will be able to see what happens, 09:09.760 --> 09:11.760 when we are using the math expression, 09:11.760 --> 09:12.760 and when we are not using the math expression, 09:12.760 --> 09:15.760 and we will be able to see that the packets are being accepted, 09:15.760 --> 09:18.760 or dropped in the other case. 09:18.760 --> 09:21.760 So let me, this, 09:21.760 --> 09:25.760 all right, 09:25.760 --> 09:28.760 just a little right, 09:28.760 --> 09:34.760 better, a bit better, 09:34.760 --> 09:38.760 I can try to make it, 09:38.760 --> 09:40.760 I will try like this, 09:41.760 --> 09:43.760 I need to be worried about the formatting, 09:43.760 --> 09:44.760 so, 09:44.760 --> 09:46.760 all right. 09:46.760 --> 09:48.760 So right now, 09:48.760 --> 09:50.760 what's going to happen is on the left side, 09:50.760 --> 09:54.760 I'm going to log in into the machine, 09:54.760 --> 09:58.760 where we are going to configure the math expression, 09:58.760 --> 10:03.760 so in the rule set that we have, 10:03.760 --> 10:09.760 we have output a table with a chain in the output hook, 10:09.760 --> 10:11.760 and there I'm using, 10:11.760 --> 10:15.760 I'm going to run a programming C that I wrote, 10:15.760 --> 10:16.760 because as I said, 10:16.760 --> 10:17.760 the NFT code is, 10:17.760 --> 10:19.760 you suspect code is not ready, 10:19.760 --> 10:23.760 so I wrote a C program to test this with, 10:23.760 --> 10:25.760 dealing with all the main language stuff, 10:25.760 --> 10:28.760 and I have inserted the, 10:28.760 --> 10:30.760 the math expression rule, 10:30.760 --> 10:34.760 and now I'm going to run another C program to get the byte code, 10:34.760 --> 10:35.760 because again, 10:35.760 --> 10:36.760 well, 10:36.760 --> 10:37.760 if you can see, 10:37.760 --> 10:39.760 it's similar to the one that they show on the, 10:39.760 --> 10:41.760 on the slides, 10:41.760 --> 10:45.760 and now on the right side, 10:45.760 --> 10:47.760 I'm going to log in, 10:47.760 --> 10:50.760 and I'm going to show the rule set. 10:56.760 --> 10:57.760 Okay, 10:57.760 --> 10:58.760 so there, 10:58.760 --> 11:00.760 what we have on the right side, 11:00.760 --> 11:02.760 the formatting is a bit bad, 11:02.760 --> 11:03.760 but what we have, 11:04.760 --> 11:05.760 if the TTL is 31, 11:05.760 --> 11:07.760 in the ICMP packet, 11:07.760 --> 11:09.760 we are going to accept it, 11:09.760 --> 11:10.760 and if the TTL is 30, 11:10.760 --> 11:12.760 we are going to drop it. 11:12.760 --> 11:15.760 So now we are going to ping that using 11:15.760 --> 11:17.760 the option 30, 11:17.760 --> 11:21.760 and as we are using the math expression on the output hook, 11:21.760 --> 11:22.760 whatever we said, 11:22.760 --> 11:23.760 the TTL, 11:23.760 --> 11:24.760 we are going to increase it by one. 11:24.760 --> 11:26.760 This is usually not obviously pretty useful, 11:26.760 --> 11:27.760 but it's for the, 11:27.760 --> 11:29.760 just for the testing. 11:29.760 --> 11:30.760 So the packets are, 11:30.760 --> 11:31.760 sorry, 11:32.760 --> 11:33.760 isn't it very dangerous? 11:33.760 --> 11:34.760 Yes, 11:34.760 --> 11:35.760 so this is just for the testing, 11:35.760 --> 11:37.760 usually you should do this only on the forward hook, 11:37.760 --> 11:40.760 and to do transferings for wording, 11:40.760 --> 11:42.760 but right now, 11:42.760 --> 11:44.760 let's do this for testing. 11:44.760 --> 11:45.760 Yeah, 11:45.760 --> 11:47.760 so we have done the ping, 11:47.760 --> 11:49.760 and it's going well. 11:49.760 --> 11:51.760 Now we've finished the rule set, 11:51.760 --> 11:53.760 so the math expression is gone, 11:53.760 --> 11:56.760 so we are not increasing the TTL anymore. 11:57.760 --> 11:59.760 Okay, 11:59.760 --> 12:02.760 and now we ping, 12:02.760 --> 12:07.760 and the packets are falling into the TTL 30 rule, 12:07.760 --> 12:09.760 and therefore I've been dropped, 12:09.760 --> 12:10.760 so the ping is not working, 12:10.760 --> 12:11.760 because well, 12:11.760 --> 12:13.760 the TTL is not being increased anymore. 12:13.760 --> 12:14.760 So as you said, 12:14.760 --> 12:15.760 yes, 12:15.760 --> 12:17.760 it's very dangerous to do this, 12:17.760 --> 12:20.760 the idea to use the TTL expression is, 12:20.760 --> 12:22.760 the math expression for TTL, 12:22.760 --> 12:24.760 is for forwarding only, 12:24.760 --> 12:26.760 and well, 12:26.760 --> 12:28.760 just to make a router, 12:28.760 --> 12:30.760 do not reduce the TTL, 12:30.760 --> 12:34.760 if you want to have some transparent process in the middle. 12:34.760 --> 12:36.760 But yeah, 12:36.760 --> 12:38.760 I just did this for simplicity, 12:38.760 --> 12:41.760 and avoid having too many things, 12:41.760 --> 12:45.760 because I need to make it short for the demo. 12:45.760 --> 12:47.760 So that's it. 12:47.760 --> 12:52.760 The idea about this is that we plan to be open 12:52.760 --> 12:54.760 about what kind of use case, 12:54.760 --> 12:56.760 do they use at half, 12:56.760 --> 13:00.760 for operations, 13:00.760 --> 13:02.760 and support them. 13:02.760 --> 13:03.760 And that's it. 13:03.760 --> 13:04.760 Thank you. 13:04.760 --> 13:05.760 Very much. 13:05.760 --> 13:07.760 Thank you. 13:13.760 --> 13:14.760 In your architecture, 13:14.760 --> 13:17.760 is it the user space code that is generating this code? 13:17.760 --> 13:18.760 Sorry. 13:18.760 --> 13:19.760 In your architecture, 13:19.760 --> 13:21.760 is it the user space code that is generating 13:21.760 --> 13:24.760 instructions for the virtual machine? 13:24.760 --> 13:25.760 Yes. 13:25.760 --> 13:27.760 So the user space is sending the learning messages, 13:27.760 --> 13:29.760 configuring everything on kernel side. 13:29.760 --> 13:31.760 That's how you understand it. 13:31.760 --> 13:34.760 I mean, the actual code generation. 13:34.760 --> 13:36.760 What do you mean, sorry? 13:36.760 --> 13:38.760 You showed some examples of code. 13:38.760 --> 13:39.760 This byte code. 13:39.760 --> 13:40.760 Yeah, exactly. 13:40.760 --> 13:41.760 Oh, yes. 13:41.760 --> 13:42.760 This byte code is in a sense, 13:42.760 --> 13:44.760 how the NF tables rules are turning out. 13:44.760 --> 13:47.760 It is being generated on user space side. 13:47.760 --> 13:50.760 Yes, I created a C program to generate this. 13:50.760 --> 13:53.760 Because I think you have some use cases where you have 13:53.760 --> 13:56.760 discontinuous or discontinuous speed fields. 13:56.760 --> 13:57.760 I think the terms. 13:57.760 --> 13:58.760 Yes. 13:58.760 --> 14:01.760 And is this something that you are also looking at? 14:01.760 --> 14:02.760 Yes. 14:02.760 --> 14:04.760 We have data mine. 14:04.760 --> 14:08.760 But the idea is that we are waiting for people to, 14:08.760 --> 14:09.760 because this is quite new. 14:09.760 --> 14:12.760 People was not expecting to be able to operate with whatever 14:12.760 --> 14:13.760 field. 14:13.760 --> 14:16.760 That's a new thing in the NF tables. 14:16.760 --> 14:19.760 And we wanted to wait to hear 14:19.760 --> 14:23.760 what they need to increase, what they need to operate with. 14:23.760 --> 14:26.760 And therefore provide support for discontinuous fields. 14:26.760 --> 14:28.760 But it's a mind. 14:28.760 --> 14:31.760 And we are trying to make it flexible enough to support 14:31.760 --> 14:36.760 those cases in the future. 14:36.760 --> 14:40.760 You have tied to the presentation about some doing math. 14:40.760 --> 14:41.760 Sorry. 14:41.760 --> 14:45.760 You tied to the presentation about doing some math. 14:45.760 --> 14:50.760 When I hear your math, I always reply for it. 14:50.760 --> 14:53.760 Does it mean that you have implementation of four to 14:53.760 --> 14:55.760 end, which inside it? 14:55.760 --> 14:58.760 How do you do math? 14:58.760 --> 15:00.760 How do you implement math? 15:00.760 --> 15:04.760 Is it four to end, which inside or how do you do that? 15:04.760 --> 15:09.760 So actually it's quite simple right now because we have some ways 15:09.760 --> 15:12.760 in the kind of mathematical stuff. 15:12.760 --> 15:15.760 I mean, not super complex, but we can divide. 15:15.760 --> 15:16.760 You can multiply. 15:16.760 --> 15:18.760 Are we running up? 15:18.760 --> 15:20.760 No, that's my point. 15:20.760 --> 15:21.760 No. 15:21.760 --> 15:22.760 But you can always. 15:22.760 --> 15:23.760 Yeah. 15:23.760 --> 15:25.760 But I mean, that's usually it's better to implement 15:25.760 --> 15:27.760 four machines and let's say it and do it. 15:27.760 --> 15:29.760 Do any math after that. 15:29.760 --> 15:31.760 It's flexible and scalable. 15:31.760 --> 15:32.760 Thank you. 15:43.760 --> 15:44.760 All right. 15:44.760 --> 15:45.760 Any other questions? 15:45.760 --> 15:46.760 Thank you. 15:46.760 --> 15:47.760 Oh, is there one up? 15:47.760 --> 15:48.760 Did you want the afternoon? 15:48.760 --> 15:49.760 Yep. 15:51.760 --> 15:53.760 I wonder about the syntax there. 15:53.760 --> 15:57.760 I would have expected a wreck on the right-hand side of the assignment 15:57.760 --> 16:00.760 operator in the math line. 16:00.760 --> 16:04.760 So all these syntax, if you are an NFTable user, you're 16:04.760 --> 16:06.760 kind of ignoring this kind of internal. 16:06.760 --> 16:10.760 It's all the user space that you usually use when you say NFTable 16:10.760 --> 16:12.760 translate that whatever generates a bytecode. 16:12.760 --> 16:15.760 And this is kind of a representation of what 16:15.760 --> 16:17.760 is actually happening in the background. 16:17.760 --> 16:20.760 Because here, for example, you are not 16:20.760 --> 16:24.760 specifying if you look at the syntax, which is the 16:24.760 --> 16:28.760 syntax at the top is what you will use as an end user. 16:28.760 --> 16:31.760 And here, you're not saying payload expression. 16:31.760 --> 16:36.760 You're just specifying IP had a TTL field. 16:36.760 --> 16:41.760 But NFTables translate that into low-level things. 16:41.760 --> 16:42.760 Use this expression. 16:42.760 --> 16:46.760 This kind of module with this specific values and 16:46.760 --> 16:51.760 the bit mask and a lot of details that NFTables 16:51.760 --> 16:55.760 resolve on its own so you don't need to do it. 16:55.760 --> 16:56.760 Okay. 16:56.760 --> 16:57.760 Thanks. 16:57.760 --> 16:59.760 Thank you. 16:59.760 --> 17:01.760 Thank you very much. 17:01.760 --> 17:02.760 Thank you. 17:06.760 --> 17:09.760 Thank you.