# External access dynamically to p4

**URL:** <https://forum.p4.org/t/external-access-dynamically-to-p4/257>\
**Category:** Uncategorized\
**Created:** [March 2, 2022, 8:00pm UTC](https://forum.p4.org/t/external-access-dynamically-to-p4/257 "2022-03-02T20:00:52Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![Elihai](https://avatars.discourse-cdn.com/v4/letter/e/779978/32.png) [@Elihai](https://forum.p4.org/u/Elihai)\
**Post date:** [March 2, 2022, 8:00pm UTC](https://forum.p4.org/t/external-access-dynamically-to-p4/257/1 "2022-03-02T20:00:52Z")

</div>

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.

---

<div class="post-metadata">

**Author:** ![ederollora](https://sea1.discourse-cdn.com/flex019/user_avatar/forum.p4.org/ederollora/32/21_2.png) [@ederollora](https://forum.p4.org/u/ederollora)\
**Post date:** [March 2, 2022, 8:13pm UTC](https://forum.p4.org/t/external-access-dynamically-to-p4/257/2 "2022-03-02T20:13:52Z")

</div>

Hi Elihai,

> [@Elihai](#):
>
> I need a way to access to external code (python for example) from the p4 code during the running of the network.

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

When you say:

> [@Elihai](#):
>
> after receive a new TCP connection

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](https://github.com/kevinbird61/p4-researching/blob/819a4cd2dba417e27b4e7602651d29da9dfe8c09/src/fundamental/learning-switch/p4_controller.py). Another example [here](https://github.com/jafingerhut/p4-guide/tree/7b60e42d8aa3e7afe11d630d7f3357bff3064bb9/ptf-tests/packetinout) from the [p4-guide](https://github.com/jafingerhut/p4-guide).

Cheers,

---

<div class="post-metadata">

**Author:** ![Elihai](https://avatars.discourse-cdn.com/v4/letter/e/779978/32.png) [@Elihai](https://forum.p4.org/u/Elihai)\
**Post date:** [March 9, 2022, 8:36pm UTC](https://forum.p4.org/t/external-access-dynamically-to-p4/257/3 "2022-03-09T20:36:43Z")

</div>

Thanks for your quick answer.

> [@ederollora](#):
>
> Another example [here](https://github.com/jafingerhut/p4-guide/tree/7b60e42d8aa3e7afe11d630d7f3357bff3064bb9/ptf-tests/packetinout) from the [p4-guide](https://github.com/jafingerhut/p4-guide).

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.

---

<div class="post-metadata">

**Author:** ![ederollora](https://sea1.discourse-cdn.com/flex019/user_avatar/forum.p4.org/ederollora/32/21_2.png) [@ederollora](https://forum.p4.org/u/ederollora)\
**Post date:** [March 9, 2022, 9:08pm UTC](https://forum.p4.org/t/external-access-dynamically-to-p4/257/4 "2022-03-09T21:08:45Z")

</div>

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:

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

```

S2:

```auto
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.

```auto
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:

```auto
// 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,
