p4lang / p4c-bm Goto Github PK
View Code? Open in Web Editor NEWGenerates the JSON configuration for the behavioral-model (bmv2), as well as the C/C++ PD code
License: Apache License 2.0
Generates the JSON configuration for the behavioral-model (bmv2), as well as the C/C++ PD code
License: Apache License 2.0
bmv2 does not support this and would probably crash at some point if such a program was actually used to forward packets
it is hard to define good semantics for operations on VL fields, which is why the P4_16 spec limits what can be done with them: https://p4lang.github.io/p4-spec/docs/P4-16-v1.0.0-spec.html#sec-varbit-string
clone_ingress_pkt_to_ingress
/clone_ingress_pkt_to_egress
is not supported for the ingress/egress pipeline, respectively. For clone_ingress_pkt_to_ingress
the compiler gives the error:
Semantic error: Invalid reference to clone_ingress_pkt_to_ingress in file /bla/bla/bla.p4 at line 123: object was not defined
Hi ,
I have attached a eth0 (real netdev interface of nic ) to the bmv2(c++) switch. I did that by passing the eth0 as a parameter along with the json file to the switch, while configuring the switch with the compiled p4 program. Now I want to know in which port in the bmv2 switch will receive the packets. I mean is there a mapping like the following. I assumed this kind of mapping as I saw something similar in one of the tutorial slide.
app switch(bmv2)
veth0-->veth1 (port0)
veth2-->veth3 (port1)
veth4-->veth5 (port2)
veth6-->veth7 (port3)
Also could someone point me to the source code file where veth1, veth3, veth5 are instantiated in the bmv2 switch.
Before this commit to the behavioral-model repository in March 2018, p4c-bmv2 and behavioral-model had the same assumptions about how push operations in the JSON file worked: p4lang/behavioral-model@9131ed9
After that commit, the default builds of behavioral-model changed, but p4c-bmv2 did not change to update with it.
If you encounter this, options you have:
Use latest p4c and behavioral-model together, which have common assumptions on how the BMv2 JSON push operation works (which is: the new pushed headers are invalid, and when compiling P4_14 programs, the p4_14 compiler when creating the BMv2 JSON file should insert add_header primitive operations after push operations, to make the newly inserted headers valid)
Use p4c-bmv2, and also use the option mentioned in the commit message linked above when building behavioral-model, i.e. "The legacy implementation can be toggled by passing the
--disable-WP4-16-stacks
flag to configure."
Convince someone, or yourself, to update p4c-bmv2 to follow the new behavior implemented by behavioral-model.
Hi everyone,
I'm trying to understand the code but unfortunately it misses comments !!!!
I was wondering if you could provide the researchers as well as developer with the comments in the codes.
Regards,
Alireza.
I recently used P4 to do a load balancing experiment with multiple paths. If there are four equivalent paths, when a packet arrives, I want to get the queue length of each path and find out the path of the shortest queue , and send packets to that shortest queue path.(the topo is shown as below,find the shortest depart queue from s1->s2,s1->s3,s1->s4,s1->s5,and send packet to the shortest link.)
h1-------------| |--------s2--------| |----- h7
| | | |
h2-------------| |--------s3--------| |---- -h8
|--------s1--- | | ------- s6-----|
h3-------------| |--------s4--------| |----- h9
| | | |
h4-------------| |--------s5--------| |------- h10
My idea is to define four registers, get the length of each queue and store them in registers, and then get the minimum value by comparing them one by one.
I found that there is a metadata about the queue in p4c.
header queueing_metadata_t {
bit<48> enq_timestamp;
bit<24> enq_qdepth;
bit<32> deq_timedelta;
bit<24> deq_qdepth;
}
register_write(qlength_reg,queueing_metadata.deq_qdepth)
I want to store the queue length in a register like this, but there are four links so that I don't know how to get the queue length of each link.
Therefore,I have two main questions:
1.Bmv2 is whether to use one queue for all ports or one queue for each port.
2.How to get the queue length of each different link?
Thanks! :)
Hello,
I am getting below error(in red) when trying to generate a json file. Please help me on this.
Below is the P4 code for which I am trying to generate a json file.
/* -- P4_16 -- */
#include <core.p4>
#include <v1model.p4>
const bit<16> TYPE_IPV4 = 0x800;
/*************************************************************************
*********************** H E A D E R S ***********************************
*************************************************************************/
typedef bit<9> egressSpec_t;
typedef bit<48> macAddr_t;
typedef bit<32> ip4Addr_t;
header ethernet_t {
macAddr_t dstAddr;
macAddr_t srcAddr;
bit<16> etherType;
}
header ipv4_t {
bit<4> version;
bit<4> ihl;
bit<8> diffserv;
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 {
/* empty */
}
struct headers {
ethernet_t ethernet;
ipv4_t ipv4;
}
/*************************************************************************
*********************** P A R S E R ***********************************
*************************************************************************/
parser ParserImpl(packet_in packet,
out headers hdr,
inout metadata meta,
inout standard_metadata_t standard_metadata) {
state start {
transition parse_ethernet;
}
state parse_ethernet {
packet.extract(hdr.ethernet);
transition select(hdr.ethernet.etherType) {
TYPE_IPV4: parse_ipv4;
default: accept;
}
}
state parse_ipv4 {
packet.extract(hdr.ipv4);
transition accept;
}
}
/*************************************************************************
************ C H E C K S U M V E R I F I C A T I O N *************
*************************************************************************/
control verifyChecksum(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 ingress(inout headers hdr, inout metadata meta, inout standard_metadata_t standard_metadata) {
action drop() {
mark_to_drop();
}
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;
}
actions = {
ipv4_forward;
drop;
NoAction;
}
size = 1024;
default_action = NoAction();
}
apply {
if (hdr.ipv4.isValid()) {
ipv4_lpm.apply();
}
}
}
/*************************************************************************
**************** E G R E S S P R O C E S S I N G *******************
*************************************************************************/
control egress(inout headers hdr, inout metadata meta, inout standard_metadata_t standard_metadata) {
apply { }
}
/*************************************************************************
************* C H E C K S U M C O M P U T A T I O N **************
*************************************************************************/
control computeChecksum(
inout headers hdr,
inout metadata meta)
{
apply {
update_checksum(true,
{ hdr.ipv4.version,
hdr.ipv4.ihl,
hdr.ipv4.diffserv,
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);
}
}
/*************************************************************************
*********************** D E P A R S E R *******************************
*************************************************************************/
control DeparserImpl(packet_out packet, in headers hdr) {
apply {
packet.emit(hdr.ethernet);
packet.emit(hdr.ipv4);
}
}
/*************************************************************************
*********************** S W I T C H *******************************
*************************************************************************/
V1Switch(
ParserImpl(),
verifyChecksum(),
ingress(),
egress(),
computeChecksum(),
DeparserImpl()
) main;
Hi everyone,
I am new to P4. I changed some of the python files in the P4c-bmv2 directory for the purpose of development and research.
I run the following commands to make the changes:
sudo python setup.py clean
sudo python setup.py build
sudo python setup.py install
However, the changes I applied to the pythons files don't apply.
Any idea?
Regards,
Alireza.
The P4 Language Specification document defines the following syntax for bit-vector constants:
const_value ::= [ "+" | - ] [ width_spec ] unsigned_value
However, the width_spec part does not seem to be supported by the compiler. For example, it refuses to parse the following line:
modify_field(eth.etherType, 16'0xffff)
but has no problems with:
modify_field(eth.etherType, 0xffff)
I also notice that the compiler supports the following syntax that is not described in the spec:
modify_field(eth.etherType, 0xff ++ 0xff)
Is this bitvector concatenation? Should it be included in the language spec?
Tried to do a VPATH make in a separate directory (../../build/p4c-bm)
cd ../../build/p4c-bm
../../src/p4c-bm/configure --prefix=...
make
It produced the following error:
$ make
make all-recursive
make[1]: Entering directory `/home/vgurevich/test/build/p4c-bm'
Making all in .
make[2]: Entering directory `/home/vgurevich/test/build/p4c-bm'
rm -f p4c_bm/config.py p4c_bm/config.py.tmp
sed -e 's|@pkgdatadir[@]|/home/vgurevich/test/install/share/p4c_bm|g' ../../src/p4c-bm/p4c_bm/config.py.in >p4c_bm/config.py.tmp
/bin/bash: p4c_bm/config.py.tmp: No such file or directory
make[2]: *** [p4c_bm/config.py] Error 1
make[2]: Leaving directory `/home/vgurevich/test/build/p4c-bm'
make[1]: *** [all-recursive] Error 1
make[1]: Leaving directory `/home/vgurevich/test/build/p4c-bm'
make: *** [all] Error 2
The reason seems to be that configure forgets to create p4c_bm subdirectory in the build directory.
Once I create it manually, the build process works fine.
when compile p4 source code which is similar to TLV_parsing , p4c-bm stuck after output
parsing successful
semantic checking successful
Header type standard_metadata_t not byte-aligned , adding padding
Thanks for the help ,
John
By caching thrift library?
Using p4c-bmv2 (1.3.0-28cdcef0), expressions such as the following compile just fine:
add_to_field(routing_metadata.test, 1 + ((b + 0xFFFFFFFF) & 0xFFFFFFFF & (routing_metadata.temp)))
But if I add a bit-width specifier to any integer constant (e.g., 32'0xFFFFFFFF), I get a parse error.
Hello,
Could you please let me know why am I getting error(in red) when trying to generate a Json file.
Below is the code
/*************************************************************************
*********************** H E A D E R S ***********************************
*************************************************************************/
typedef bit<9> egressSpec_t;
typedef bit<48> macAddr_t;
typedef bit<32> ip4Addr_t;
header ethernet_t {
macAddr_t dstAddr;
macAddr_t srcAddr;
bit<16> etherType;
}
header ipv4_t {
bit<4> version;
bit<4> ihl;
bit<8> diffserv;
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 {
/* empty */
}
struct headers {
ethernet_t ethernet;
ipv4_t ipv4;
}
/*************************************************************************
*********************** P A R S E R ***********************************
*************************************************************************/
parser ParserImpl(packet_in packet,
out headers hdr,
inout metadata meta,
inout standard_metadata_t standard_metadata) {
state start {
transition parse_ethernet;
}
state parse_ethernet {
packet.extract(hdr.ethernet);
transition select(hdr.ethernet.etherType) {
TYPE_IPV4: parse_ipv4;
default: accept;
}
}
state parse_ipv4 {
packet.extract(hdr.ipv4);
transition accept;
}
}
/*************************************************************************
************ C H E C K S U M V E R I F I C A T I O N *************
*************************************************************************/
control verifyChecksum(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 ingress(inout headers hdr, inout metadata meta, inout standard_metadata_t standard_metadata) {
action drop() {
mark_to_drop();
}
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;
}
actions = {
ipv4_forward;
drop;
NoAction;
}
size = 1024;
default_action = NoAction();
}
apply {
if (hdr.ipv4.isValid()) {
ipv4_lpm.apply();
}
}
}
/*************************************************************************
**************** E G R E S S P R O C E S S I N G *******************
*************************************************************************/
control egress(inout headers hdr, inout metadata meta, inout standard_metadata_t standard_metadata) {
apply { }
}
/*************************************************************************
************* C H E C K S U M C O M P U T A T I O N **************
*************************************************************************/
control computeChecksum(
inout headers hdr,
inout metadata meta)
{
apply {
update_checksum(true,
{ hdr.ipv4.version,
hdr.ipv4.ihl,
hdr.ipv4.diffserv,
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);
}
}
/*************************************************************************
*********************** D E P A R S E R *******************************
*************************************************************************/
control DeparserImpl(packet_out packet, in headers hdr) {
apply {
packet.emit(hdr.ethernet);
packet.emit(hdr.ipv4);
}
}
/*************************************************************************
*********************** S W I T C H *******************************
*************************************************************************/
V1Switch(
ParserImpl(),
verifyChecksum(),
ingress(),
egress(),
computeChecksum(),
DeparserImpl()
) main;
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.