nsg-ethz / p4-learning Goto Github PK
View Code? Open in Web Editor NEWCompilation of P4 exercises, examples, documentation, slides for learning or teaching
License: GNU General Public License v3.0
Compilation of P4 exercises, examples, documentation, slides for learning or teaching
License: GNU General Public License v3.0
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?
Pre-built OVA package: ova is linked to https://drive.google.com/open?id=1tubqk0PGIbX759tIzJGXqex08igFfzpD, but the file isn't available, could you please check?
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.
Hi,
I am trying to populate my match-action table using table_add
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?
Is there any detail descriptions about the hash function in p4switch,for i am confuse about the exercise"https://github.com/nsg-ethz/p4-learning/tree/master/exercises/11-Packet-Loss-Detection" in compute hash indexes for stream meter.
.
I think the base value may bigger than the max value,so i want to how this hash function compute?Thanks in advance.
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?
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:
Thanks for your comments
in line 5, I think the IP address should be 10.0.1.1/32
Am I correct?
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.
I want to know what the function "bm_mgmt_get_info()" do, and where can i get these information from?
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:
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:
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!
`
There seem to be bugs when attempting to add range match entries to tables. Specifically, I have been unable to successfully add such entries via controller.py , as the range match never seems to hit.
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.
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!
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, 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 queue cannot work. h1 and h2 get the same bandwidth.
What should I do? BTW, what is the principle of priority queue?
My question is the same with what asked in the p4 maillist : http://lists.p4.org/pipermail/p4-dev_lists.p4.org/2018-March/003465.html
Thanks a lot.
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
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.
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:
Thanks in advance.
How can we add commands at host like mentioned in P4 language official tutorials? here
Thank you
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.
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 :)
I want to know why when i add a cpu-port to all switch the program in" https://github.com/nsg-ethz/p4-learning/tree/master/exercises/08-Simple_Routing " doesn't work?
The debugger is not enabled on the switch.
I tried something, but it didn't work. How could I enable debugger on the 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?
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.
I have 3 questions.
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 astopic, device_id, ctx_id, list_id, buffer_id, num
from here.
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.
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.
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)
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
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?
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
I'm runing the solution of the Exercice fast reroute, but there is an issue, it's doesn't work, Any help please
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
##############################################################################################
Hello everyone,
I'm doing the recirculate example in this repo. When I run the program, I got this error:
I've checked the directory /usr/local/share/p4c/p4include/v1model.p4 and I see that the recirculate extern exists
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.
I am doing a project with Mininet. I used the P4 virtual machine before and I found the "mx" function was really useful. Is it possible to integrate it into the ordinary Mininet?
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?
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!
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?
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
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.