-
Notifications
You must be signed in to change notification settings - Fork 48
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Port traffic redirection with logic bypass #10
Comments
Hi, I think that this can be easily done with a change to the parser logic (I think that we cannot do this in the control block, because it would add a dependency that would make the program not fit in the 12 stages). p4app-switchML/dev_root/p4/parsers.p4 Lines 204 to 209 in 7ded628
and this flag makes the packet skip the SwitchML processing logic and go to the forwarder table that forwards regular traffic using the dst mac address. You cannot achieve what you ask by simply changing the forwarder table, because you need first to skip the processing logic to reach that table. If you look at the main Ingress control block p4app-switchML/dev_root/p4/switchml.p4 Lines 137 to 138 in 7ded628
you can see that the forwarder table, which is in charge of forwarding regular traffic, is only applied for packet types that are not p4app-switchML/dev_root/p4/types.p4 Lines 142 to 147 in 7ded628
The parser code is marking as The way that I think is best suited to do this is to use port metadata, which is a feature available in the parser. Each ingress hardware port can be associated with a small amount (64 bits) of static data that is prepended to each packet in the ingress pipeline. These metadata can be set by the controller for each port differently. The port metadata header is the first header that the parser sees in a packet, even before ethernet. The controller could set a "processing type" in the port metadata for each port (something like SKIP, PROCESS, or RECIRCULATE). Then the parse_port_metadata parser can select the next parser state using this value (RECIRCULATE ➝ parse_recirculate, else ➝ parse_ethernet). Then the parse_ethernet stage can use this value, and if it is SKIP, transition to accept_regular, which would make it skip the processing logic and reach the forwarder table. This solution is also the one to use to avoid hardcoding the ports to use for recirculation, like the parse_port_metadata parser is doing now. p4app-switchML/dev_root/p4/parsers.p4 Lines 50 to 58 in 7ded628
This would allow to use any port for recirculation (selected at runtime by the controller), and would allow to have a folded pipe option also on 2-pipes switches like yours. Currently, the port metadata is only used to set 2x16 bits values for the drop simulator (used to randomly drop a chosen percentage of the packets, to test the retransmission logic). These values are set by the controller, per port, in drop_simulator.py.
We can use up to 64 bits for the port metadata, so there is plenty of space to add the flag we need. |
Hi, Thank you very much for the detailed response and for providing an overview of the proposed solution. I understand that two modifications are needed in order to support the said case. First, we need to modify the ingress parser in order to skip the processing logic for all packets coming from a specific port. I understand that the method you explained of utilizing the port metadata available at the parse, would be the best way of doing this giving the ability to the controller to dynamically select the port that its traffic would skip the processing logic. However, in order to test out my setup until such a full flex feature is implemented, could I just test it manually by including something like this
in the The second necessary modification would then be to change the Thank you again, |
Even without the change to the I think that the change that you need is to modify the transition out of the the
This would transition to And finally, yes, you need to modify the forwarder table, to match on the ingress port and set the egress port accordingly. This change requires to change also the controller code to add the ingress port to the set of match values here: p4app-switchML/dev_root/controller/forwarder.py Lines 81 to 87 in 7ded628
|
Thanks again for the input. I have indeed modified the
in order to be able to match to the ingress port beside the dst address. However, I'm not sure how to properly configure the table. When I'm populating the table through the controller with a simple rule for forwarding from one port to another with the following:
I end up with a rule being written in the table (along with the regular entries the controller populates the forwarder table) which looks like this:
Doing a simple ping from the device on the port in question doesn't seem to be redirecting the traffic via the port looping (the frame counter for these ports remain at 0 and I have enabled the relevant ports from the controller) which suggest the rule is not triggered. I was thinking if I could insert a rule with a wildcard (like |
Hi, self.table.entry_add(self.target, [
self.table.make_key([
self.gc.KeyTuple('hdr.ethernet.dst_addr', MAC_ADDRESS),
self.gc.KeyTuple('ig_intr_md.ingress_port', ingress_dev_port)])
], [
self.table.make_data([self.gc.DataTuple('egress_port', egress_dev_port)],
'Ingress.forwarder.set_egress_port')
]) To add a rule with a wildcard, you can use ternary match, like this table does: p4app-switchML/dev_root/p4/arp_icmp_responder.p4 Lines 66 to 80 in 7ded628
and this is how you add an entry. p4app-switchML/dev_root/controller/arp_icmp_responder.py Lines 61 to 96 in 7ded628
A ternary match requires both a value and a mask. Also, when there is a ternary match, you can have overlapping rules (a packet can match more than one rule), so there is an additional priority field to specify which rule should be applied first (0 is the highest priority). There is also an example about ternary match in the open-tofino repo here. |
Hi, Thanks again for the comments and support on this. I have indeed changed the forwarding table to a ternary match on the keys as shown below:
for which I'm populating an entry for enabling the forwarding of all traffic from
and then the normal destination mac forwarding rules are added like this:
I am trying to validate the configuration( emulating the bigger topology by loopbacking two ports with an external link and forwarding all traffic from one port via the external link) with the simplest example possible by pinging one machine from another via the port looping with the external link. I'm changing the
in order to track things more clearly through the packet counters of BFRT and what I see is that on one direction of the ping the packet goes through the loopback link but then isn't forwarded to the target's port and on the other way, the packet does seem to be redirected through all hops correctly and exit through the target host's port but is not detected via a regular Is there something obviously wrong with my approach ? Could there be some other part of SwitchML's functionality (e.g., the |
My first guess is that the first packet that goes out when you do a ping is an arp packet. That packet will have as destination mac address the broadcast address FF:FF:FF:FF:FF:FF that doesn't match any rule and is supposed to be flooded on all ports using the flood default rule and the multicast group you commented. Try adding the arp rule manually first so that an arp resolution is not needed. The The reason why you don't see the packet with tcpdump could be that the packet format is wrong and dropped by the NIC, or maybe a checksum is incorrect. The best way to debug this is to use the snapshot feature in Tofino, that allows to see how a packet is processed by your P4 program (similar to the tofino model log, but more low level). With a snapshot you can see what rule a packet matched, and what headers are valid when the packet is going out (to check that the format is correct). |
Thanks again for the comments. I've managed to identify the issue that was causing the unexpected packet processing behavior. In SwitchML's parser: p4app-switchML/dev_root/p4/parsers.p4 Lines 46 to 59 in 7ded628
all pipe 1,2,3 ports are considered to be recirculation which follows a specific parsing logic, extracting some SwitchML specific headers. I realized that the extra link I was using to emulate the bigger topology was connected to a pair of front panel ports corresponding to pipe 3, thus all traffic coming in from those ports was redirected to Does this mean that we are meant to be using only pipe 1 ports for testing and the rest are used by the SwitchML logic inside the switch? Thank you, |
Hi, In the P4 program a port number is a 9 bit number (the number in the Currently, our program is hardcoding that ports in the pipes 1,2,3 are considered in loopback. I mentioned it in the first answer, and until we make the changes I described, we can only use the ports in pipe 0 to connect to servers. Does this work for you? |
Hi,
I would like to benchmark SwitchML on an emulated topology bigger than that of a single rack. To do so, I plan to reuse the same Tofino switch(APS Networks BF2556X-1T) with SwitchML deployed on it and redirect all traffic coming in from a specific port into another port without any processing done. That port would then be physically connected to yet another port which will consume the traffic regularly via the SwitchML logic.
I was wondering whether this is something that is already possible with the existing P4 model and SwitchML controller program? If not, is there a way I could modify the Forwarder table in
forwarder.p4
(populated via theforwarder.py
on the control plane) to accommodate this functionality without messing the underlying SwitchML logic? Practically, I need the traffic from that specific port to bypass the SwitchML aggregation logic in the switch and just be redirected out of another port (and vice versa for the return journey). From what I understand, currently, the forwarder table matches on ethernet addresses. Could this be somehow extended to accommodate the case without jeopardizing the underlying functionality of the P4 program?Thank you,
The text was updated successfully, but these errors were encountered: