clean-up trailing whitespace (#453)
These changes have been mostly auto-generated with: find . -type f -print0 | xargs -0 perl -pi -e 's/ +$//' Signed-off-by: Radostin Stoyanov <rstoyanov@fedoraproject.org>
This commit is contained in:
committed by
GitHub
parent
071b89ad30
commit
50f397b249
@@ -14,7 +14,7 @@ would be in a single pod of a fat tree topology.
|
||||

|
||||
|
||||
Switch s1 will be configured with a P4 program that implements a
|
||||
simple stateful firewall (`firewall.p4`), the rest of the switches will run the
|
||||
simple stateful firewall (`firewall.p4`), the rest of the switches will run the
|
||||
basic IPv4 router program (`basic.p4`) from the previous exercise.
|
||||
|
||||
The firewall on s1 should have the following functionality:
|
||||
@@ -62,21 +62,21 @@ up a switch in Mininet to test its behavior.
|
||||
[pod-topo/topology.json](./pod-topo/topology.json)
|
||||
|
||||
2. You should now see a Mininet command prompt. Try to run some iperf
|
||||
TCP flows between the hosts. TCP flows within the internal
|
||||
TCP flows between the hosts. TCP flows within the internal
|
||||
network should work:
|
||||
```bash
|
||||
mininet> iperf h1 h2
|
||||
```
|
||||
|
||||
TCP flows from hosts in the internal network to the outside hosts
|
||||
TCP flows from hosts in the internal network to the outside hosts
|
||||
should also work:
|
||||
```bash
|
||||
mininet> iperf h1 h3
|
||||
```
|
||||
```
|
||||
|
||||
TCP flows from the outside hosts to hosts inside the
|
||||
internal network should NOT work. However, since the firewall is not
|
||||
implemented yet, the following should work:
|
||||
TCP flows from the outside hosts to hosts inside the
|
||||
internal network should NOT work. However, since the firewall is not
|
||||
implemented yet, the following should work:
|
||||
```bash
|
||||
mininet> iperf h3 h1
|
||||
```
|
||||
@@ -118,11 +118,11 @@ logic replaced by `TODO` comments. Your implementation should follow
|
||||
the structure given in this file --- replace each `TODO` with logic
|
||||
implementing the missing piece.
|
||||
|
||||
**High-level Approach:** We will use a bloom filter with two hash functions
|
||||
to check if a packet coming into the internal network is a part of
|
||||
an already established TCP connection. We will use two different register
|
||||
arrays for the bloom filter, each to be updated by a hash function.
|
||||
Using different register arrays makes our design amenable to high-speed
|
||||
**High-level Approach:** We will use a bloom filter with two hash functions
|
||||
to check if a packet coming into the internal network is a part of
|
||||
an already established TCP connection. We will use two different register
|
||||
arrays for the bloom filter, each to be updated by a hash function.
|
||||
Using different register arrays makes our design amenable to high-speed
|
||||
P4 targets that typically allow only one access to a register array per packet.
|
||||
|
||||
A complete `firewall.p4` will contain the following components:
|
||||
@@ -130,32 +130,32 @@ A complete `firewall.p4` will contain the following components:
|
||||
1. Header type definitions for Ethernet (`ethernet_t`), IPv4 (`ipv4_t`) and TCP (`tcp_t`).
|
||||
2. Parsers for Ethernet, IPv4 and TCP that populate `ethernet_t`, `ipv4_t` and `tcp_t` fields.
|
||||
3. An action to drop a packet, using `mark_to_drop()`.
|
||||
4. An action (called `compute_hashes`) to compute the bloom filter's two hashes using hash
|
||||
algorithms `crc16` and `crc32`. The hashes will be computed on the packet 5-tuple consisting
|
||||
of IPv4 source and destination addresses, source and destination port numbers and
|
||||
4. An action (called `compute_hashes`) to compute the bloom filter's two hashes using hash
|
||||
algorithms `crc16` and `crc32`. The hashes will be computed on the packet 5-tuple consisting
|
||||
of IPv4 source and destination addresses, source and destination port numbers and
|
||||
the IPv4 protocol type.
|
||||
5. An action (`ipv4_forward`) and a table (`ipv4_lpm`) that will perform basic
|
||||
5. An action (`ipv4_forward`) and a table (`ipv4_lpm`) that will perform basic
|
||||
IPv4 forwarding (adopted from `basic.p4`).
|
||||
6. An action (called `set_direction`) that will simply set a one-bit direction variable
|
||||
6. An action (called `set_direction`) that will simply set a one-bit direction variable
|
||||
as per the action's parameter.
|
||||
7. A table (called `check_ports`) that will read the ingress and egress port of a packet
|
||||
(after IPv4 forwarding) and invoke `set_direction`. The direction will be set to `1`,
|
||||
7. A table (called `check_ports`) that will read the ingress and egress port of a packet
|
||||
(after IPv4 forwarding) and invoke `set_direction`. The direction will be set to `1`,
|
||||
if the packet is incoming into the internal network. Otherwise, the direction will be set to `0`.
|
||||
To achieve this, the file `pod-topo/s1-runtime.json` contains the appropriate control plane
|
||||
entries for the `check_ports` table.
|
||||
8. A control that will:
|
||||
1. First apply the table `ipv4_lpm` if the packet has a valid IPv4 header.
|
||||
2. Then if the TCP header is valid, apply the `check_ports` table to determine the direction.
|
||||
3. Apply the `compute_hashes` action to compute the two hash values which are the bit positions
|
||||
in the two register arrays of the bloom filter (`reg_pos_one` and `reg_pos_two`).
|
||||
When the direction is `1` i.e. the packet is incoming into the internal network,
|
||||
`compute_hashes` will be invoked by swapping the source and destination IPv4 addresses
|
||||
and the source and destination ports. This is to check against bloom filter's set bits
|
||||
3. Apply the `compute_hashes` action to compute the two hash values which are the bit positions
|
||||
in the two register arrays of the bloom filter (`reg_pos_one` and `reg_pos_two`).
|
||||
When the direction is `1` i.e. the packet is incoming into the internal network,
|
||||
`compute_hashes` will be invoked by swapping the source and destination IPv4 addresses
|
||||
and the source and destination ports. This is to check against bloom filter's set bits
|
||||
when the TCP connection was initially made from the internal network.
|
||||
4. **TODO:** If the TCP packet is going out of the internal network and is a SYN packet,
|
||||
set both the bloom filter arrays at the computed bit positions (`reg_pos_one` and `reg_pos_two`).
|
||||
Else, if the TCP packet is entering the internal network,
|
||||
read both the bloom filter arrays at the computed bit positions and drop the packet if
|
||||
4. **TODO:** If the TCP packet is going out of the internal network and is a SYN packet,
|
||||
set both the bloom filter arrays at the computed bit positions (`reg_pos_one` and `reg_pos_two`).
|
||||
Else, if the TCP packet is entering the internal network,
|
||||
read both the bloom filter arrays at the computed bit positions and drop the packet if
|
||||
either is not set.
|
||||
9. A deparser that emits the Ethernet, IPv4 and TCP headers in the right order.
|
||||
10. A `package` instantiation supplied with the parser, control, and deparser.
|
||||
@@ -171,18 +171,18 @@ h3 and h1 should be blocked by the firewall.
|
||||
|
||||
### Food for thought
|
||||
|
||||
You may have noticed that in this simple stateful firewall, we are adding
|
||||
new TCP connections to the bloom filter (based on outgoing SYN packets).
|
||||
However, we are not removing them in case of TCP connection teardown
|
||||
(FIN packets). How would you implement the removal of TCP connections that are
|
||||
You may have noticed that in this simple stateful firewall, we are adding
|
||||
new TCP connections to the bloom filter (based on outgoing SYN packets).
|
||||
However, we are not removing them in case of TCP connection teardown
|
||||
(FIN packets). How would you implement the removal of TCP connections that are
|
||||
no longer active?
|
||||
|
||||
Things to consider:
|
||||
- Can we simply set the bloom filter array bits to `0` on
|
||||
receiving a FIN packet? What happens when there is one hash collision in
|
||||
Things to consider:
|
||||
- Can we simply set the bloom filter array bits to `0` on
|
||||
receiving a FIN packet? What happens when there is one hash collision in
|
||||
the bloom filter arrays between two _active_ TCP connections?
|
||||
- How can we modify our bloom filter structure so that the deletion
|
||||
operation can be properly supported?
|
||||
- How can we modify our bloom filter structure so that the deletion
|
||||
operation can be properly supported?
|
||||
|
||||
### Troubleshooting
|
||||
|
||||
|
||||
@@ -74,7 +74,7 @@ parser MyParser(packet_in packet,
|
||||
************ C H E C K S U M V E R I F I C A T I O N *************
|
||||
*************************************************************************/
|
||||
|
||||
control MyVerifyChecksum(inout headers hdr, inout metadata meta) {
|
||||
control MyVerifyChecksum(inout headers hdr, inout metadata meta) {
|
||||
apply { }
|
||||
}
|
||||
|
||||
@@ -89,14 +89,14 @@ control MyIngress(inout headers hdr,
|
||||
action drop() {
|
||||
mark_to_drop(standard_metadata);
|
||||
}
|
||||
|
||||
|
||||
action ipv4_forward(macAddr_t dstAddr, egressSpec_t port) {
|
||||
standard_metadata.egress_spec = port;
|
||||
hdr.ethernet.srcAddr = hdr.ethernet.dstAddr;
|
||||
hdr.ethernet.dstAddr = dstAddr;
|
||||
hdr.ipv4.ttl = hdr.ipv4.ttl - 1;
|
||||
}
|
||||
|
||||
|
||||
table ipv4_lpm {
|
||||
key = {
|
||||
hdr.ipv4.dstAddr: lpm;
|
||||
@@ -109,7 +109,7 @@ control MyIngress(inout headers hdr,
|
||||
size = 1024;
|
||||
default_action = drop();
|
||||
}
|
||||
|
||||
|
||||
apply {
|
||||
if (hdr.ipv4.isValid()) {
|
||||
ipv4_lpm.apply();
|
||||
@@ -133,10 +133,10 @@ control MyEgress(inout headers hdr,
|
||||
|
||||
control MyComputeChecksum(inout headers hdr, inout metadata meta) {
|
||||
apply {
|
||||
update_checksum(
|
||||
hdr.ipv4.isValid(),
|
||||
update_checksum(
|
||||
hdr.ipv4.isValid(),
|
||||
{ hdr.ipv4.version,
|
||||
hdr.ipv4.ihl,
|
||||
hdr.ipv4.ihl,
|
||||
hdr.ipv4.diffserv,
|
||||
hdr.ipv4.totalLen,
|
||||
hdr.ipv4.identification,
|
||||
|
||||
@@ -108,7 +108,7 @@ parser MyParser(packet_in packet,
|
||||
************ C H E C K S U M V E R I F I C A T I O N *************
|
||||
*************************************************************************/
|
||||
|
||||
control MyVerifyChecksum(inout headers hdr, inout metadata meta) {
|
||||
control MyVerifyChecksum(inout headers hdr, inout metadata meta) {
|
||||
apply { }
|
||||
}
|
||||
|
||||
@@ -154,7 +154,7 @@ control MyIngress(inout headers hdr,
|
||||
hdr.ethernet.dstAddr = dstAddr;
|
||||
hdr.ipv4.ttl = hdr.ipv4.ttl - 1;
|
||||
}
|
||||
|
||||
|
||||
table ipv4_lpm {
|
||||
key = {
|
||||
hdr.ipv4.dstAddr: lpm;
|
||||
@@ -184,7 +184,7 @@ control MyIngress(inout headers hdr,
|
||||
size = 1024;
|
||||
default_action = NoAction();
|
||||
}
|
||||
|
||||
|
||||
apply {
|
||||
if (hdr.ipv4.isValid()){
|
||||
ipv4_lpm.apply();
|
||||
@@ -232,10 +232,10 @@ control MyEgress(inout headers hdr,
|
||||
|
||||
control MyComputeChecksum(inout headers hdr, inout metadata meta) {
|
||||
apply {
|
||||
update_checksum(
|
||||
hdr.ipv4.isValid(),
|
||||
update_checksum(
|
||||
hdr.ipv4.isValid(),
|
||||
{ hdr.ipv4.version,
|
||||
hdr.ipv4.ihl,
|
||||
hdr.ipv4.ihl,
|
||||
hdr.ipv4.diffserv,
|
||||
hdr.ipv4.totalLen,
|
||||
hdr.ipv4.identification,
|
||||
|
||||
@@ -108,7 +108,7 @@ parser MyParser(packet_in packet,
|
||||
************ C H E C K S U M V E R I F I C A T I O N *************
|
||||
*************************************************************************/
|
||||
|
||||
control MyVerifyChecksum(inout headers hdr, inout metadata meta) {
|
||||
control MyVerifyChecksum(inout headers hdr, inout metadata meta) {
|
||||
apply { }
|
||||
}
|
||||
|
||||
@@ -154,7 +154,7 @@ control MyIngress(inout headers hdr,
|
||||
hdr.ethernet.dstAddr = dstAddr;
|
||||
hdr.ipv4.ttl = hdr.ipv4.ttl - 1;
|
||||
}
|
||||
|
||||
|
||||
table ipv4_lpm {
|
||||
key = {
|
||||
hdr.ipv4.dstAddr: lpm;
|
||||
@@ -184,7 +184,7 @@ control MyIngress(inout headers hdr,
|
||||
size = 1024;
|
||||
default_action = NoAction();
|
||||
}
|
||||
|
||||
|
||||
apply {
|
||||
if (hdr.ipv4.isValid()){
|
||||
ipv4_lpm.apply();
|
||||
@@ -238,10 +238,10 @@ control MyEgress(inout headers hdr,
|
||||
|
||||
control MyComputeChecksum(inout headers hdr, inout metadata meta) {
|
||||
apply {
|
||||
update_checksum(
|
||||
hdr.ipv4.isValid(),
|
||||
update_checksum(
|
||||
hdr.ipv4.isValid(),
|
||||
{ hdr.ipv4.version,
|
||||
hdr.ipv4.ihl,
|
||||
hdr.ipv4.ihl,
|
||||
hdr.ipv4.diffserv,
|
||||
hdr.ipv4.totalLen,
|
||||
hdr.ipv4.identification,
|
||||
|
||||
Reference in New Issue
Block a user