Skip to content

Example #1 Simple L2 switch with Bmv2 target

Damu Ding edited this page Aug 25, 2022 · 2 revisions

Example #1 - Simple L2 Switch with Bmv2 target

This example describes the default P4 program running on P4Pi with BMv2. It implements two core functionalities of a simple L2 switch: 1) MAC learning (control plane support is needed) and 2) forwarding of Ethernet frames.

To this end, it consists of two tables: smac and dmac. Table smac stores the source MAC addresses learned by the switch and sends digest messages to the control plane for each unseen source MAC. Table dmac is used for forwarding Ethernet frames toward the proper direction (egress port) or applies broadcasting (Note: broadcasting in BMv2 is implemented by multi cast groups that can be configured through its PD API (the 'simple_switch_CLI' command)). As an extension, packet dropping is also allowed in both tables, so that MAC-based filtering would also be possible.

P4 source code: l2switch.p4.

Testing with WiFi access only

The following figure depicts the setup used in this example (T4P4S box is replaced with Bmv2):

Default settings of P4Pi

P4Pi runs a DHCP daemon (dnsmasq) to assign IP addresses to devices connected through WiFi. The Bmv2 switch interconnects the wireless interface wlan0 and the linux bridge br1. However, the 1GE Ethernet port eth0 is not used in this example. The default management IP address is assigned to br0. Through this IP address (192.168.4.1) the P4Pi node is accessible (e.g., via the web interface or SSH).

Step 0 - Connecting to P4Pi Access Point

Connect your laptop to the wireless access point called "p4pi". After that your laptop will get an IP address assigned by the DHCP service (from the default address pool 192.168.4.0/24).

Step 1 - Switching to Bmv2 target and starting l2switch example

You can launch l2switch example with Bmv2 via the web interface. Alternatively, you can launch it manually in an ssh terminal:

sudo systemctl stop t4p4s.service
sudo systemctl disable t4p4s.service
sudo echo 'l2switch' > /root/t4p4s-switch
sudo systemctl enable bmv2.service
sudo systemctl restart bmv2.service

Step 2 - Configure multicast group for broadcasting

In case of Bmv2, broadcasting is implemented with multicasting the packet to all the ports. It can be confiured with command simple_switch_CLI (not bmv2-p4rtshell in this example) via ssh or the terminal on the web interface. In the P4 program multicast group 1 is used as broadcasting group that can be configured with the following lines in the shell:

mc_mgrp_create 1
mc_node_create 0 0 1
mc_node_associate 1 0

It will create multicast group 1, then create handle 0 with port 0 and port 1, and finally assign handle 0 to the multicast group 1.

Step 3 - Test with the ping tool

After all these steps, you should be able to ping the IP (192.168.4.150 by default) assigned to br1 (br1 is inside netns gigport) from your laptop.

ping 192.168.4.150

ICMP Echo requests go through the Bmv2 switch and terminate at br1, while Echo replies follow the opposite way back to your laptop.

Step 4 - Test with blocking ICMP replies

The L2 switch program broadcasts all the incoming packets.

In our simple setup, it only relays packets between the two ports of Bmv2 switch. In this scenario, we simply add a table entry to table smac to drop packets coming from br1 and see what happens with ICMP Echo replies.

We first check the MAC address of br1. To this end, add the following command in the SSH terminal:

sudo ip netns exec gigport ip addr show dev br1 | grep ether

Right after "link/ether" you should find the MAC address of br1.

Then, we launch P4Runtime shell that can be used to fill tables. In the SSH terminal:

bmv2-p4rtshell l2switch

In the P4Runtime shell you can use various commands to read, write and modify objects in the P4 pipeline. For more details, see the Github site of P4Runtime shell. In our case the following commands can be used to create a table entry, set the key and the action and add it to the table:

te = table_entry["ingress.smac"](action="ingress.drop")
te.match["hdr.ethernet.srcAddr"] = "<mac address>"
te.insert

As you can see this setup will drop all packets where the Ethernet source MAC is . Replacing this with the MAC of br1, the ICMP Echo replies will be dropped. The P4Runtime shell can be left by the 'exit' command. In the SSH terminal, we can easily check what happens:

sudo ip netns exec gigport tcpdump -i br1 icmp

One can see that all the ICMP Echo requests arrive and replies are generated as previously, but they do not return back to the laptop. Running tcpdump on interface br0, we can see that the replies have gone, being removed by the switch.

sudo tcpdump -i br0 icmp

Testing as a hotspot sharing the Internet access of a home router (or a private network domain)

The following figure depicts another setup where P4Pi node acts as a low level relay or proxy between your laptop and your home router (or a private network) connected to the 1GE wired Ethernet port.

Low level gateway mode of P4Pi

Step 1 - Connect to P4Pi

Connect to p4pi wireless access point and open an SSH to the management IP (192.168.4.1).

Step 2 - Reconfiguring internal network settings

The following script should be executed to turn your P4Pi node into gateway mode:

sudo /root/setup_eth_wlan_bridge.sh

This script will create the settings shown in the previous figure: setup bridge br2 and connect port 1 of Bmv2 switch to the 1GE wired interface and configure new management IPs. The possible management IPs through which you can access the P4Pi node (incl. SSH, web interface, etc.) are reported by the script like this example output:

+-------------------------------------------------------------
| Management IP on the wired interface: 192.168.1.146/24
| Management IP on the wireless interface: 192.168.1.83/24
| Management IP on the wireless interface: 192.168.4.101/24
+-------------------------------------------------------------

The last IP address is configured statically and can be used as a backdoor to the P4Pi node.

Step 3 - Reconnect your laptop

It may happen that you should disconnect your laptop from the p4pi access point and reconnect again (or at least renew your IP from the local DHCP server). After that you will be able to access the networking domains (e.g., Internet) behind your P4Pi node. For example, if the wired port of your P4Pi is connected to your home router, you should be able to access the Internet. Just open your browser to test it. Note that in this case all the traffic go through th P4 pipeline running inside the Bmv2 switch.

Troubleshooting - no route to P4Pi

If you cannot access P4Pi through the management IP, the following trick can help in solving the issue:

  • Connect to the p4pi WiFi access point.
  • On your laptop, assign static IP 192.168.4.50/24 to the wireless interface.
  • Open a SSH connection to 192.168.4.1.

Functionalities to be added during the hackathon or later

  • VLAN support
  • MAC learning control plane (P4Runtime shell cannot handle digests)
Clone this wiki locally