P4/C Firewall - Two Different Approaches
This repository contains two different approaches taken to implement a Statefull Firewall on Netronome SmartNICs using P4 and Micro-C. The Statefull Firewall makes use of Network Address Translation (NAT) to protect private IP's from untrusted external networks. All packets comming from an untrusted network are dropped unless a request was made from a private host to a host on the external network after which a connection is established and traffic is allowed between the two hosts.
To get started quickly using the P4/C Firewall, use the State Table approach. For more background and comparison between different implementations or if you would like to do your own comparison, read further.
The first approach was to keep state by dynamically adding P4 rules as new connections are established. The dynamic rules allow traffic through as incomming packets hit the dynamically added rules allowing the packets to be forwarded. A default rule is in place to handle packets where dynamic rules were not added yet, sending the packets to a python controller which will then add the new rules before sending the packet back to the SmartNIC to be forwarded. Timeouts involves keeping track of the frequency at which the added rules are hit and clearing inactive rules periodically.
The second approach was to keep state by implementing a hashtable table in Micro-C to store the state of each flow. All P4 rules are static and the P4 program can forward or drop packets based on the state of that specific flow after doing a lookup in the state table. This eliminates the need to first send a packet to a controller, waiting for rules to be added before the packet can be sent back to be matched again before it is forwarded. A controller is only used for initial configuration and for timeouts.
Pros & Cons
In our experience the pros of the state table approach greatly outweighs the dynamic rule approach.
- Easier to implement using only P4 Code
- New packets are sent to the host first reducing performance - Controller gets congested when a large number new flows are introduced - Large number of rules to sync to Programmer Studio when debugging
- State updated quickly using primitive actions - Only static P4 rules - Higher throughput
- More advanced c progamming to impliment the primitive actions (compared to simplicity of using P4 alone) - Number of flows limited by memory available for hash table and bucket size