I have a question, I have 2 hosts conected to a switch:
h1 connected to port 1 en h2 connected to port 2.
h1 and h2 generates flux 1 and 2, respectively.
flux 1 (with header UDPport_dst=X) forward to port 3
flux 2 forward to port 4
I want to change the flux 2 forward from port 4 to port 5 when flux 1 UDP port header change to “Y” (UDPport_dst=Y)
Is it possible to do this in proactive mode? I mean, without put a new rule with the controller.
Thanks for your support
I think that you can override a flow rule that has the same match criteria of the old one, I mean UDPport_dst=Y forward to port Y can be override by UDPport_dst=Y forward to port X. In openflow you can do it, I think it works for P4 too I don’t remember trying it
Thank you for you reply. However, I think the question was confused since I put UDPport header. I edited the question for more clarity:
I have 2 hosts connected to a switch:
h1 connected to port 1 en h2 connected to port 2.
h1 and h2 generate flux 1 and 2, respectively.
flux 1 (with header VLAN=X) forward to port 3
flux 2 forward to port 4
I want to change the flux 2 forward from port 4 to port 5 when flux 1 VLAN header change to “Y” (VLAN=Y)
Is it possible to do this in proactive mode? I mean, without putting a new rule with the controller.
In summary, is it possible to change the forwarding of one flux by the header variation from another flux in proactive mode?
Hi @juanda ,
I have some issues to understand what you exactly want to do. I understand most of the text but I find this part confusing:
And more importantly, this sentence.
So my questions are, what do you mean by “when flux 1 VLAN header change to “Y” (VLAN=Y)”?
- Do you mean… when a packet’s VLAN header belonging (in principle) to flow 1, has a different VLAN (VLAN=Y)?
- Or do you mean… when the selector of the flow rule (flow 1) installed in the switch changes to match VLAN=Y?
If you say yes to point 1, then you will need an additional rule, I guess, because the expected parameters of the flow rule for flow 1 will not be matched, and you have no way to know if it did not match for the VLAN being = to Y. You still need another rule to match that new VLAN=Y and decide over a port. I am not sure, though, if the selector criteria will change for the flow rule for flow 2.
If you said yes to point 2, then you are responsible for selector changes in the flow rule of flux 1 to VLAN=Y (because I guess you still want the rule for flow 1 to match it). And when that happens, you can modify the flow rule for flow 2. According to the Openflow spec, it is possible to modify rules:
Let me check for P4Runtime…
Answer, it does:
Now the question is, do the controllers and switches have full support for flow rule (OpenFlow) and table entry (P4Runtime) modification as determined in the specifications? As far as I understand it, as long as the selector is exactly the same (i.e., match criteria), the switch should change the treatment (output port). But only tests will confirm!
I get your point. From my point of view you need to leverage the statfull capabilities of P4, such as register. Because 1 packet at a time goes through the pipeline, so you have to keep track of what is going on flux 1. Then you can put the value store in the register in a metadata and use it as trigger for the proactive forwarding. More in detail you can use the metadata as a key in a table or you apply an if confition on it and then apply the action that you want.
thank you @ederollora for your detailed response and support.
It’s about the point 1.
It’s not necessarily the VLAN header. I put this for an instance.
What I am trying to say is that at one point a header of flow 1 changes from X to Y. So, when this change happens, I want to change the forwarding of flow 2.
Normally when you define a flow (flow 1), you do it determining some parameters (let’s say a 5-tuple, but it can be a 3-tuple or another criterion). For instance, we can define a flow for being source IP (v4) address = 192.168.1.100, destination IP address = 192.168.1.101, IP protocol = TCP, source TCP port = 57142 and destination TCP port = 80. In other words: (192.168.1.100, 192.168.1.101, 0x06, 57142, 80). Therefore, all the packets that match these values will be considered as being from the same 5-tuple flow. If you consider that the source port changes for a new packet, then the rule regarding this 5-tuple will not match. In fact, changing the source port to any number that is different to 57142 is considered to belong to a new flow (not related to flow 1), because you defined a 5-tuple to match for flow 1.
When a packet with a different source port arrives to a switch (OpenFlow or P4) we know it will not match the flow rule or table entry for flow 1. Now, two things could happen.
- If the packet matches another rule, then you should know why, and you should either remove the rule or do whatever you need to do. But this case does not help in your use case. You need the packet to be sent to the controller.
- If it does match any rule but the controller one, it will be sent to the controller (if the proper rule has been installed for this). When the packet is sent to the controller, you should analyze the packet and determine if it is similar to a packet from flow 1 but one parameter (like the source port) has changed. If you can determine this case (that one parameter changed from what flow 1 was supposed to look like), then you can modify the rule for flow 2.
As far as I understand your use case, then this is what I would do.
@ederollora , I try to avoid sending a message to the controller (reactive mode)
What if I use metadata in the table entry for flow 1 to register that flow 1 changes the header value and then put the metadata (for matching) in the other table entry for flow 2 to forward change.
It’s that possible?
@DavideS , The metadata is for all flow entries or for each flow entry?
If I write metadata in flow entry 1, It’s possible use this metadata in flow entry 2 to match it?
I mean you can use a metadata from a flow entry and then use this metadata in another flow entry to match?
Now your use case is a little more specific, which is good to continue the discussion. Still, it would be nice if you make a very specific example of your use case because the implementations and solutions vary a lot from case to case. Expecting a VLAN header or the source port change is different. And we might be able to give a better answer. So the closest you get to your actual implementation, the better. For instance, if you expect the destination UDP port to change (and only that header/field) it is much easier than detecting any possible change in the packet. You can always hard-code the packet parameters and make a literal comparison (if statement) for every header/field you expect that could change in the P4 program, but this is an unrealistic approach (that’s why we have tables, among other things).
The main problem I see is that (1) if a header (that is part of the criteria to determine flow 1) changes, then this new packet (with a different header/field) is not a packet belonging to flow 1 anymore. (2) If the header is outside the scope of the tuple that determines flow 1 then this is much easier.
In case of (1) you have a concern because I cannot see how you exactly match a flow entry for flow 1 but also determine if a key parameter has changed. These are two contradictory things, IMO. You can indeed match ranges of values, but to make this possible, I need to investigate a little bit. Until you make an exact use case with the headers you plan to use to determine flow 1 and which headers exactly you expect to change, I cannot give you the best answer. It would also help if you add some code of how your program looks now.
In case of (2), this is much easier because you can make a table match flow 1 and then determine in a second (or third) table if a particular header changed. And once you determine if some key header changed, for instance, if you miss hitting a table it means that a planned value did not match for a particular header, then you can set a local metadata field that can be a key in the table entry for flow 2 in a different table. I will give you some (pseudo) code once I know for sure your exact use case