External access dynamically to p4

Hi,
I need a way to access to external code (python for example) from the p4 code during the running of the network.
The idea is to change the forwarding tables that are implemented according the tutorial of basic_forwarding after receive a new TCP connection.
We thought about registers but we saw that for now it haven’t implemented for external use.
Thanks, Elihai.

Hi Elihai,

This sentence is very confusing, so I will make some assumptions.

When you say:

Do you mean a SYN packet?

I think what you are looking for is a PACKET_IN. The switch can create a new packet for the controller when in a particular case (e.g., a table that matches SYN packets).

As an example, you can find a learning switch here. Another example here from the p4-guide.

Cheers,

Thanks for your quick answer.

This solution implements only one switch. I need a solution that can simultaneously uses 2 switches. The first one knows to dynamically edit its table (like PACKET_IN mechanism), and the second one routes in the basic option of forwarding statically.
Best Regards,
Elihai.

Hi @Elihai,

The example I posted works for one or more switches, no matter your use case. You only have to make it work differently for each switch (i.e., install some rules for one switch and others or none for another one). In one switch you can forward the packet to the controller if there is no match on a table, and in the second one just only follow the rules installed previously. If having a control plane that works differently for each switch is a problem, you could install a different P4 program for each switch, having a table with a different default action.

S1:

table ipv4_lpm {
      key = {
          hdr.ipv4.dstAddr: lpm;
      }
      actions = {
          ipv4_forward;
          send_packet_in;
          drop;
          NoAction;
      }
      size = 1024;
      default_action = send_packet_in();
}

S2:

table ipv4_lpm {
      key = {
          hdr.ipv4.dstAddr: lpm;
      }
      actions = {
          ipv4_forward;
          send_packet_in;
          drop;
          NoAction;
      }
      size = 1024;
      default_action = NoAction();
}

Alternatively, you could also detect if a table has had a match and execute an action if it has not matched.

if (hdr.ipv4.isValid()) {
    if (ipv4_lpm.apply().miss){
        //Add this if statement to only one of the switches code
        send_packet_in();
    }
}

And if none of the options work for, you could keep the same code for both switch but then use a table to trigger a PACKET_IN if no previous match was done. Then just make sure a rule is installed in one of the switches:

// Install 1 rule for switch 1 (empty key, send_packet_in action)
// No rule for switch 2
table packet_in_tb{
    key = {
    }
    actions = {
        send_packet_in;
        NoAction;
    }
    size = 1;
    default_action = NoAction();
}

if (hdr.ipv4.isValid()) {
    if (ipv4_lpm.apply().miss){
        packet_in_tb.apply();
    }
}

I know myself and I am most probably missing an obvious solution so anyone please feel free to provide a solution to this if I missed it.

Hope that helps @Elihai

Cheers,