GithubHelp home page GithubHelp logo

nsg-ethz / p4-learning Goto Github PK

View Code? Open in Web Editor NEW
504.0 32.0 191.0 395.92 MB

Compilation of P4 exercises, examples, documentation, slides for learning or teaching

License: GNU General Public License v3.0

P4 48.12% Python 51.60% Shell 0.28%
p4 p4-exercises networking teaching p4-tutorials

p4-learning's People

Contributors

edgar-costa avatar jafingerhut avatar jpmondet avatar jurijnota avatar lvanbever avatar romain-jacob avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

p4-learning's Issues

Question about forwarding.

Hello, I'm testing 06-Heavy_Hitter_Detection, I add a register to count the packets recorded in the switch. That is, adding the following codes in MyIngress
register<bit<32>>(1) count_pkt;
action write_count_pkt() {
bit<32> tmp;
count_pkt.read(tmp, 0);
tmp = tmp + 1;
count_pkt.write(0, tmp);
}
and add write_count_pkt(); in apply{}, like
write_count_pkt();
update_bloom_filter();

Then, I read the register in simple_switch_CLI. The register value is twice the number of packets sent. However, when check the counters in 07-Count-Min-Sketch, which uses fowarding table instead of ipv4.lpm, the sum of each array of counters is equal to that of packets sent.

I would like to know why this happened.

Thank you for your time!

Queue length for priority queueing

Hello,

I am somewhat new to P4 coding and for a personal project of mine, I would be interested to know how exactly one is supposed to set a particular queue length when enabling priority queues. I am aware that the current simple_switch version in the bmv2 git has those enabled by default, and it seems to me that you would want to set the length as anything other than 64 under there : https://github.com/p4lang/behavioral-model/blob/main/targets/simple_switch/simple_switch.cpp#L201
However, you specifically wrote that you could do it individually for each queue id and that you would explain if asked. So, provided you see this and are able to answer, I would like you to give me some advice.
Thank you for your help.

Questions about clone3

I want to know the cloned packet with a non empty third parameter.Is the parameter are combined into the cloned packet's payload or somewhere else?

How to use cli for resubmit_recirculate example?

Hi,
I'm running the resubmit_recirculate example to understand the difference between resubmit and recirculate -- at the bottom of the readme it says the following:

By default, `send.py` transmits packets with *Identification* field set to 255.

To read the state of `recirculate_register` we can use the cli:

RuntimeCmd: register_read MyEgress.recirculate_register

Which cli is it referring to, and how do I send this RuntimeCmd?

Question about exercise RSVP

I want to know how to compute CIR and PIR by using bw, what does the number 0.125 (appers in function get_meter_rates_from_bw in rsvp_controller.py) mean? And does the size of burst_size affect bandwidth?

How to setup rate for each of the priority queues

If we enable priority queuing and set up queue rate using simple_Switch_CLI, does the rate is applicable for all the priority for of a single port?

Or, we can set the rate separately for each of the queue for a single port?

sniff in Multicast example

why when I sniff with scapy in one of my hosts in the network and in another side send a multicast packet (as your example nothing more), in the received packet I have :

###[ Ethernet ]### 
  dst       = ff:ff:ff:ff:ff:ff
  src       = 00:00:0a:00:01:02
  type      = 0x1111
###[ Raw ]### 
     load      = '\x00\x00\x00\x01\x00\x00\x00\x10\x00\x00\x00\x01\x00\x00\x00\x10'

why load is '\x00\x00\x00\x01\x00\x00\x00\x10\x00\x00\x00\x01\x00\x00\x00\x10'

but, I use the bottom script to send a packet and as you see there is no RAW data :

#! /usr/bin/env python
import os
import time
from scapy.all import *

mac = get_if_hwaddr(conf.iface)
pkt =  Ether(src = mac, dst = 'ff:ff:ff:ff:ff:ff', type=0x1111)
print("Each 5 second send a multicast packet")
while True:
 sendp(pkt)
 time.sleep(5)

Thank you for the feedback in advance.
@jafingerhut @edgar-costa

Can't use iperf in congestion aware load balancing

I am trying to use iperf to send UDP packets between h1 and h2 ( simple topology in congestion aware load balancing) like in multiqueing example but UDP server is not receiving any packets. Can someone explain what is wrong?

Priority queuing in Simple Switch

Hello everyone,

I'm using the latest Development VM released in April.
I've read the BMv2 Simple Switch article and also looked into the multiqueuing.p4 example. They all said that if I want to use multiple priority queues, I have to uncomment the line:
#define SSWITCH_PRIORITY_QUEUEING_ON

But when I go to the simple_switch.h file at the directory /home/vagrant/behavioral-model/targets/simple_switch, I can't find the above line, what I saw is in the following image:
image
So my question is do I need to type the line #define SSWITCH_PRIORITY_QUEUEING_ON like you see in the image, then compile and install bmv2 again to use the feature?

Also when I scroll down, I see this:
image
Am I supposed to changes the `default_nb_queues_per_port = 1 to another value? Does changing this value has the same effect as I use multiple priority queues?

Thanks!

`

raise IndexError("Layer [%s] not found" % lname) IndexError: Layer [None] not found

salam'
I m knew with P4-learning repo.
The controller program of '04-L2_Learning' exercice is well running, and the broadcast table is well populated.
But when I send a ping between hosts like below:
mininet> h3 ping h1
PING 10.0.0.1 (10.0.0.1) 56(84) bytes of data.
64 bytes from 10.0.0.1: icmp_seq=1 ttl=64 time=75.2 ms
64 bytes from 10.0.0.1: icmp_seq=2 ttl=64 time=12.5 ms
^C
--- 10.0.0.1 ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 1001ms
rtt min/avg/max/mdev = 12.514/43.881/75.249/31.368 ms
mininet>

I get an error in the controller API:
Error
Thanks for your comments

Unstable bandwidth with iperf

As you can see I am getting fluctuating bandwidth result. Is there any way I can fix this? Or alternatively, is there any way I can limit bandwidth with 50Mbits/s in JSON file?

Screenshot 2021-10-25 at 00 42 41

Copy to cpu example

Hi, thanks for sharing this repo. I was looking at the simple example for copy to cpu. I noticed that the receive.py sniff on that cpu port to receive the packets. My question is: can I also send packets from the controller to the switch directly?

My goal is to have something like this: for the topology h1---s1---h2, h1 will send 10 packets to h2, but switch will intercept all these packets and forward to controller. I want the controller to be able to receive and store these 10 packets, do some processing on these packets, maybe wait for a few seconds, then send it back down to the switch and the 10 packets will then be forwarded to h2.

About sswitch_runtime

I meet this problem when I run the sentence "sudo python3 l2_learning_controller.py s1 cpu"
The problem:

Traceback (most recent call last):
File "/home/wly/p4-learning/exercises/04-L2_Learning/thrift/l2_learning_controller.py", line 4, in
from p4utils.utils.sswitch_thrift_API import SimpleSwitchThriftAPI
File "/home/wly/p4-utils/p4utils/utils/sswitch_thrift_API.py", line 34, in
from sswitch_runtime import SimpleSwitch
ModuleNotFoundError: No module named 'sswitch_runtime'

How can I fix it in a right way? Thanks.

multicast

As I read in the readme file in the multicast example, only packets with an ethernet type of 0x1234 get multicasted to all the ports.
I tried to extend this example to one switch with 8 ports and just ports 1, 3, 5, 7 as subscribers work with group number one, and ports 2, 4, 6, 8 work with a new group, which means number 2.
Therefore I defied new TYPE_BROADCAST, for example, 0x5678 and added new mc_mgrp_create, mc_node_create and mc_node_associate in s1-commands.txt, In additional added one more "else if (hdr.ethernet.etherType == 0x5678)" in Ingress Processing section.

Problem:

  1. line 6 -> const bit<16> TYPE_BROADCAST = 0x1234; ( but i have two different)
  2. hdr.broadcast.id = ?
  3. hdr.broadcast.type = ?
    ( In fact, I want to have two publishers in this switch and two different groups of subscribers)

Thanks in advance.

multicast-me.txt
s1-commands.txt

Logging seems broken

Although I am able to compile the p4 app, but logging seems broken. Any suggestions?
Screenshot 2021-08-13 at 10 45 34

Switch debugger

The debugger is not enabled on the switch.
I tried something, but it didn't work. How could I enable debugger on the switch?

Got the below mentioned error while executing this example.

Got this error while executing this example.
##############################################################################################
Building mininet topology.
p4c --target bmv2 --arch v1model --std p4-16 "debugging_table.p4" -o "/home/p4/p4-tools/p4-learning/examples/debugging_table"
debug.p4(59): [--Werror=type-error] error: Field clone_spec is not a member of structure struct standard_metadata
standard_metadata.clone_spec : exact;
^^^^^^^^^^
/usr/local/share/p4c/p4include/v1model.p4(61)
struct standard_metadata_t {
^^^^^^^^^^^^^^^^^^^
debug.p4(70): [--Werror=type-error] error: Field lf_field_list is not a member of structure struct standard_metadata
standard_metadata.lf_field_list : exact;
^^^^^^^^^^^^^
/usr/local/share/p4c/p4include/v1model.p4(61)
struct standard_metadata_t {
^^^^^^^^^^^^^^^^^^^
debug.p4(72): [--Werror=type-error] error: Field resubmit_flag is not a member of structure struct standard_metadata
standard_metadata.resubmit_flag : exact;
^^^^^^^^^^^^^
/usr/local/share/p4c/p4include/v1model.p4(61)
struct standard_metadata_t {
^^^^^^^^^^^^^^^^^^^
debug.p4(75): [--Werror=type-error] error: Field recirculate_flag is not a member of structure struct standard_metadata
standard_metadata.recirculate_flag : exact;
^^^^^^^^^^^^^^^^
/usr/local/share/p4c/p4include/v1model.p4(61)
struct standard_metadata_t {
^^^^^^^^^^^^^^^^^^^
Compilation Error
##############################################################################################

How to create a topology

Hello, I'm sorry to bother you. I used the following program to build the topology, but I don't know what the error message means. Can you help me with it?

import json
import argparse
import networkx

topo_base = {
"p4_src": "collect_flow.p4",
"cli": True,
"pcap_dump": True,
"enable_log": True,
"exec_scripts": [
{
"cmd": "python routing-controller.py",
"reboot_run": True
}
],
"topology": {
"assignment_strategy": "l3",
"default":
{
"bw": 10,
"queue_length": 30000
},
}
}

def create_clos_topo(num_hosts=32,num_switches=4):
topo_base["topology"]["links"] = []

# connect hosts with switches
for i in range(1, num_hosts-15):
    topo_base["topology"]["links"].append(["h{}".format(i),"s{}".format(1)])

for i in range(num_hosts-15,num_hosts+1):
    topo_base["topology"]["links"].append(["h{}".format(i), "s{}".format(2)])

# connect switches
topo_base["topology"]["links"].append(["s{}".format(1), "s{}".format(3)])
topo_base["topology"]["links"].append(["s{}".format(1), "s{}".format(3)])
topo_base["topology"]["links"].append(["s{}".format(2), "s{}".format(3)])
topo_base["topology"]["links"].append(["s{}".format(2), "s{}".format(3)])
topo_base["topology"]["links"].append(["s{}".format(2), "s{}".format(4)])
topo_base["topology"]["links"].append(["s{}".format(2), "s{}".format(4)])

topo_base["topology"]["hosts"] = {"h{0}".format(i): {} for i in range(1, num_hosts+1)}
topo_base["topology"]["switches"] = {"s{0}".format(i): {} for i in range(1, num_switches+1)}

def main():
pass

if name == 'main':
parser = argparse.ArgumentParser()
parser.add_argument('--output_name', type=str, required=False, default="clos_four_switches_4.json")
# parser.add_argument('-n', type=str, required=False, default=4)
# parser.add_argument('-d', type=str, required=False, default=2)
args = parser.parse_args()
# create_clos_topo(int(args.d), int(args.n))
create_clos_topo(32,4)
json.dump(topo_base, open(args.output_name, "w"), sort_keys=True, indent=2)

image
Reading JSON configuration file...
"l3" assignment strategy selected.
Traceback (most recent call last):
File "/usr/local/bin/p4run", line 11, in
load_entry_point('p4utils', 'console_scripts', 'p4run')()
File "/home/p4/p4-tools/p4-utils/p4utils/p4run.py", line 739, in main
verbosity=args.verbosity)
File "/home/p4/p4-tools/p4-utils/p4utils/p4run.py", line 341, in init
self.l3()
File "/home/p4/p4-tools/p4-utils/p4utils/mininetlib/network_API.py", line 2650, in l3
assert not self.is_multigraph()
AssertionError

Questions about examples/digest_messages

I have 3 questions.

  1. What's the exact struct about message received by the controller through digest? Where can I get the information?

I read the controller script get_digest.py, and find that there are many other fields besides the user-defined metadata in p4 code from here , such as topic, device_id, ctx_id, list_id, buffer_id, num from here.

  1. Will simple_switch add several messages to a digest message? If it will, how can I make the switch send one message at a time instead several messages?

I read the controller script get_digest.py, and find that the controller will use a loop to unpack the received messages from here.

  1. what does the function bm_learning_ack_buffer() do? And where can I get the information about it?

The function is also in the script get_digest.py from here.

Issue in recirculate example

Hello everyone,

I'm doing the recirculate example in this repo. When I run the program, I got this error:
image

I've checked the directory /usr/local/share/p4c/p4include/v1model.p4 and I see that the recirculate extern exists
image

Here is the .p4 program:

/* -*- P4_16 -*- */
#include <core.p4>
#include <v1model.p4>

const bit<16> TYPE_IPV4 = 0x800;
#define RECIRCULATE_TIMES 5

/*************************************************************************
*********************** H E A D E R S  ***********************************
*************************************************************************/

typedef bit<9>  egressSpec_t;
typedef bit<48> macAddr_t;
typedef bit<32> ip4Addr_t;

/* TCP/IP Headers */

header ethernet_t {
    macAddr_t dstAddr;
    macAddr_t srcAddr;
    bit<16>   etherType;
}

header ipv4_t {
    bit<4>    version;
    bit<4>    ihl;
    bit<8>    tos;
    bit<16>   totalLen;
    bit<16>   identification;
    bit<3>    flags;
    bit<13>   fragOffset;
    bit<8>    ttl;
    bit<8>    protocol;
    bit<16>   hdrChecksum;
    ip4Addr_t srcAddr;
    ip4Addr_t dstAddr;
}



struct metadata {
    bit<8> counter;
}

struct headers {
    ethernet_t   ethernet;
    ipv4_t       ipv4;
}


/*************************************************************************
*********************** P A R S E R  ***********************************
*************************************************************************/

parser MyParser(packet_in packet,
                out headers hdr,
                inout metadata meta,
                inout standard_metadata_t standard_metadata) {
    state start {

        packet.extract(hdr.ethernet);
        transition select(hdr.ethernet.etherType){
            TYPE_IPV4: ipv4;
            default: accept;
        }
    }
    state ipv4 {
        packet.extract(hdr.ipv4);
        transition accept;
    }
}

/*************************************************************************
***********************  D E P A R S E R  *******************************
*************************************************************************/

control MyDeparser(packet_out packet, in headers hdr) {
    apply {
        packet.emit(hdr.ethernet);
        packet.emit(hdr.ipv4);
    }
}

/*************************************************************************
************   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) {
    apply {  }
}

/*************************************************************************
**************  I N G R E S S   P R O C E S S I N G   *******************
*************************************************************************/

control MyIngress(inout headers hdr,
                  inout metadata meta,
                  inout standard_metadata_t standard_metadata) {

    action drop() {
        mark_to_drop(standard_metadata);
    }

    apply {
        standard_metadata.egress_spec = 2;
    }
}

/*************************************************************************
****************  E G R E S S   P R O C E S S I N G   *******************
*************************************************************************/

control MyEgress(inout headers hdr,
                 inout metadata meta,
                 inout standard_metadata_t standard_metadata) {


    //To debug
    table debug {
        key = {
            meta.counter: exact;
        }
        actions = {
            NoAction;
        }
        size=1;
        default_action=NoAction();
    }

    apply {
       debug.apply();
       if (meta.counter < RECIRCULATE_TIMES){
           meta.counter = meta.counter + 1;
           recirculate({meta.counter});
       }
    }
}

/*************************************************************************
*************   C H E C K S U M    C O M P U T A T I O N   **************
*************************************************************************/

control MyComputeChecksum(inout headers hdr, inout metadata meta) {
     apply {
	update_checksum(
	    hdr.ipv4.isValid(),
            { hdr.ipv4.version,
	      hdr.ipv4.ihl,
              hdr.ipv4.tos,
              hdr.ipv4.totalLen,
              hdr.ipv4.identification,
              hdr.ipv4.flags,
              hdr.ipv4.fragOffset,
              hdr.ipv4.ttl,
              hdr.ipv4.protocol,
              hdr.ipv4.srcAddr,
              hdr.ipv4.dstAddr },
            hdr.ipv4.hdrChecksum,
            HashAlgorithm.csum16);
    }
}


/*************************************************************************
***********************  S W I T C H  *******************************
*************************************************************************/

//switch architecture
V1Switch(
MyParser(),
MyVerifyChecksum(),
MyIngress(),
MyEgress(),
MyComputeChecksum(),
MyDeparser()
) main;

Does anyone know this problem? I'm using April, 2023 Development VM.

`vagrant up` fails on macOS 10.14.6 + vagrant 2.2.5

I have not tested other host systems yet, but at least that one failed fairly early on after running vagrant up. I will create a PR later showing a change I made to the Vagrantfile on my system that enabled the command to proceed past that point, plus a few other changes, for your consideration.

In the 04-RSVP experiment, I found a problem

when a subscription request of the same priority does not meet the bandwidth allocation, the first subscription request is deleted, it should not be deleted.
In line 417 of rsvp_controller.py, it should be commented, I think it is, you can think about it again.

The queue of the P4 switch

We want to calculate the occupancy ratio of the queue, but there is no physical space size of the queue in the metadata of the P4 switch . How can we query the physical space size of the queue of the P4 switch?

detecting congestion header

In the 10- congestion aware load balancing, detecting congestion part
I can't get any printed qdepth.
whatever I write the code, host filters all message during
sniff(filter="ether proto 0x7777", iface = iface,
prn = lambda x: handle_pkt(x), lfilter=my_filter)
if I remove that filter, qdepth becomes NoneType.
besides telemetry header has enq_qdepth not enq_depth which written in receive.py code.
Could you tell me how to write loadbalancing.p4 code to print qdepth?
little help would be very helpful.

did not find a p4 program for switch s1

Hi, thanks for sharing the tutorials.

Today I want to try "recirculate" and after I do sudo p4run, it fails and log shows Exception: Did not find a p4 program for switch s1

Then I tried use python file, but it fails either. Does someone face this problem before?
Appreciate for you help :)

match-action table do not support negative number

Hi,

I am trying to populate my match-action table using table_add
1664666925982

I found when the action parameter is a negative number, it always transfers 0 to the action.
In the above example, I hope when the key==0, executes the action set with parameter -1.

Is there a way to transfer the negative number to the action parameter?

How Count-Min Sketch implement on bmv2?

Hello, in the example of Count-Min Sketch, whether each row of the sketch is placed in a different stage of the pipeline or in the same stage? I am a little confused about the relationship between the p4 program and the stage, can we use P4 program to control the use of stage? I have seen before that there are some differences between bmv2 and Tofino. Is there no stage concept on bmv2? Because it seems that only one stage can be accessed at a time on the RMT architecture, in this case, should a sketch be split into multiple stages for deployment?
Thank you in advance for taking the time to answer the question.

Priority and qid fields meaning

Hello there everyone!

I have some questions regarding the usage of multiqueue inside bmv2.

What are the meaning of both fields: qid and priority? Is there a link that I can read more about both?
For example: If i define priority = 1 and qid = 3 I'm giving the fourth qid the priority of 1? How does that work?

Thanks already!

Questions about 11-Packet-Loss-Detection

When I run the controller, when loss happend, the controller met the following error:
Traceback (most recent call last):
File "packet-loss-controller.py", line 251, in
controller.run_cpu_port_loop()
File "packet-loss-controller.py", line 240, in run_cpu_port_loop
sniff(iface=cpu_interfaces, prn=self.recv_msg_cpu)
File "/usr/lib/python2.7/dist-packages/scapy/sendrecv.py", line 620, in sniff
r = prn(p)
File "packet-loss-controller.py", line 233, in recv_msg_cpu
loss_header = LossHeader(packet.payload)
File "/usr/lib/python2.7/dist-packages/scapy/base_classes.py", line 223, in call
i.init(*args, **kargs)
File "/usr/lib/python2.7/dist-packages/scapy/packet.py", line 95, in init
self.dissect(_pkt)
File "/usr/lib/python2.7/dist-packages/scapy/packet.py", line 619, in dissect
s = self.do_dissect(s)
File "/usr/lib/python2.7/dist-packages/scapy/packet.py", line 587, in do_dissect
s, fval = f.getfield(self, s)
File "/usr/lib/python2.7/dist-packages/scapy/fields.py", line 732, in getfield
bytes = struct.unpack('!%dB' % nb_bytes , w)
struct.error: unpack requires a string argument of length 1

How to make the switches in topo use the same clock to achieve time synchronization?

We want to simulate the delay measurement in network performance, but we find that the time of each switch is activated when the packets are sent to the switch. There is no time synchronization, so we would like to ask you how to make the switches in topo use the same clock to achieve time synchronization.Or can you tell us where the code is for the switches in topo to synchronize?

hello, here is a small IP error in png

in p4-learning/exercises/05-ECMP/images/multi_hop_topo.png
h1 should has IP: 10.0.1.1, but in ur pic, it's 10.0.0.1, which is not correct, plz note that

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.