Giter Club home page Giter Club logo

p4-guide's Introduction

Introduction

This repository contains a variety of potentially useful information for those wanting to work with the P4 programming language.

Installing open source P4 development tools

There are install scripts in this repository that can assist you in building and installing the p4c and behavioral-model projects and their dependencies on some recent versions of Ubuntu or Fedora Linux systems.

See these instructions and trouble-shooting tips for using these scripts.

There are also some newer instructions here for installing IPDK on an Ubuntu 20.04 Linux system, and using the DPDK software switch to load and run P4 programs.

Articles on various P4 topics

See this page for a list of articles included in this repository.

Overview of public P4.org documentation and code repositories

Small demo P4 programs

A collection of small demo P4 programs, some of them with equivalent versions written in both P4_14 and P4_16 versions of the language.

  • includes a heavily commented P4_16 program, which by reading carefully one may learn some things about the P4_16 language.
  • Each of the demo directories includes its own README.md file with instructions for compiling the program and running it with the simple_switch software switch from the behavioral-model repository, including interactively adding table entries to the tables, and send packets using Scapy that will be processed by the software switch.

Related development tools and tips

  • Instructions for setting up several text editing programs for color highlighting P4 programs, and quickly finding definitions for named things like control blocks and tables.

  • 'Cheat sheet' of where P4_16 language constructs are allowed to be used within a program.

    • figure
    • text
    • NOTE: This describes where language constructs are allowed by the P4_16 language specification (version 1.1.0). P4_16 implementations may restrict your program to less than what is shown here, or enable extensions not described here. Ask the creator of the implementation you are using to learn more.
  • Another useful 'cheat sheet' with example snippets of code is in the p4lang/tutorials repository.

  • Some notes on using the Scapy library for creating, editing, and decoding packets, useful when creating test packets to send to a P4 program being tested, especially within the control of a general purpose programming language (i.e. Python).

Brief overview of P4

This is just enough to give you a 'flavor' of what P4 is like, in about 500 words. It assumes you are familiar with the programming language C or something very similar to it, e.g. C++ or Java.

  • Start with C.
  • Remove loops, recursive calls, pointers, malloc, and free. When your mind recovers from reeling over these drastic limitations, you will clearly realize that P4 is not a general purpose programming language. It was not designed to be.
    • Without loops or recursive calls, the work done per packet can be bounded at compilation time, which helps when targeting the highest performance P4-programmable devices.
    • Without pointers, malloc, and free, general purpose data structures like linked lists, trees, etc. having arbitrary size is not possible. You can implement trees with fixed depth, e.g. a depth 3 tree could be implemented via a sequence of 3 P4 tables.
  • Add special constructs called parsers, focused on the capabilities most needed when parsing the contents of a received packet into a sequence of headers.
    • Parsers are defined as finite state machines, with states that you must name and define what the possible transitions are between them. It is actually allowed to have loops in the parser finite state machine, but the highest performance targets will typically restrict you to loops that can be unrolled to a compile-time known maximum number of iterations, e.g. for parsing a sequence of MPLS headers at most 5 headers long (where 5, or some other value, is a number you pick in your source code).
    • P4 is focused on packet header processing. Whatever part of a packet you do not parse into some header is, for that P4 program, considered the "payload" of the packet, which is typically carried along, unmodified, with the packet when you are done processing it. You can modify header fields however you like.
  • Add special constructs called tables, where for each one you define a search key consisting of a number of packet header fields and/or values of variables in your P4 program. Each table can also have one or more actions defined for them.
    • A P4 program represents only a small fraction of a complete working system. Control plane software that would typically be running on a general purpose CPU, written in one or more general purpose programming languages like C, C++, Java, Python, etc., is responsible for adding and removing entries to these tables, selecting for each entry the search key to be matched against, and the action to be executed if, while processing a packet, that table entry is matched.
  • A P4_16 "architecture" like the Portable Switch Architecture (PSA) also defines a library of other constructs, such as packet/byte counters, meters for enforcing average packet and/or bit rates on forwarded traffic, registers for some limited kinds of stateful packet processing, and methods for recirculating a packet, multicasting it to multiple destinations, etc.
  • Fields and variables can be integers of arbitrary bit width (up to some maximum size allowed by a particular implementation), with results of arithmetic operations well defined for all operations. P4 implementations need not implement floating point arithmetic, and I expect most would not because such things are not needed for the majority of packet processing applications. P4 implementations also need not implement multiplication, division, or modulo operations, again given that such operations are often not needed for most packet processing applications.
  • Note that integer arithmetic is sufficient for implementing fixed point operations, because fixed point add/subtract/shift can be viewed as the corresponding operations on integers that are in smaller units, e.g. an integer could be used to represent time in multiples of 0.8 nanoseconds, as opposed to in units of nanoseconds, which would be convenient if an implementation had a clock speed of 1.25 GHz and measured time in integer number of clock cycles (1 cycle / 0.8 nanosec = 1.25 GHz).

Very brief comparison of P4_14 and P4_16 languages

Some advantages of P4_16 over P4_14:

  • You can write assignments that look like C/C++/Java, rather than modify_field(dst, src); all over the place, and you can have arithmetic expressions on the right-hand side instead of add_to_field/subtract_from_field/etc. This is not additional power in the language, but it is a nice convenience for those familiar with those other languages.
  • You may call controls from other controls in P4_14, but there are no parameters or return values. All side effects must be done via access to global variables. In P4_16, there are no global variables -- you may pass parameters with directionality in, out, inout.
  • Tables must be, and externs may be, defined within the scope of a control, and are then accessible only from that control, which can be useful for keeping the code that accesses those objects closer to it, and knowing where they can be accessed from. Externs are used for things like counters, meters, and registers that were part of the base P4_14 language, but in P4_16 are defined as extern add-ons in the Portable Switch Architecture specification).

Disadvantages of P4_16 vs P4_14:

  • Tool and vendor support may not have been as good for P4_16 in 2018 as it was for P4_14, but as of 2021, P4_16 is supported for most P4-programmable target devices.

p4-guide's People

Contributors

chrispsommers avatar edgar-costa avatar jafingerhut avatar jfingerh avatar khooi8913 avatar thedini 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  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

p4-guide's Issues

how can i solve this problem

Waiting 2 seconds before starting PTF test ...
[sudo] password for liuwei:
Calling target program-options parser
Adding interface veth0 as port 0
Adding interface veth2 as port 1
Adding interface veth4 as port 2
Adding interface veth6 as port 3
Adding interface veth8 as port 4
Adding interface veth10 as port 5
Adding interface veth12 as port 6
Adding interface veth14 as port 7
Server listening on 0.0.0.0:9559
/usr/local/lib/python3.10/dist-packages/ptf-0.9.3-py3.10.egg/EGG-INFO/scripts/ptf:19: DeprecationWarning: the imp module is deprecated in favour of importlib and slated for removal in Python 3.12; see the module's documentation for alternative uses
import imp
Using packet manipulation module: ptf.packet_scapy
2023-04-26 21:33:14,692 - root - INFO - Importing platform: eth
2023-04-26 21:33:14,694 - root - INFO - port map: {(0, 0): 'veth1', (0, 1): 'veth3', (0, 2): 'veth5', (0, 3): 'veth7', (0, 4): 'veth9', (0, 5): 'veth11', (0, 6): 'veth13', (0, 7): 'veth15'}
2023-04-26 21:33:14,694 - root - INFO - Autogen random seed: 71143180
Traceback (most recent call last):
File "/usr/local/bin/ptf", line 4, in
import('pkg_resources').run_script('ptf==0.9.3', 'ptf')
File "/usr/lib/python3/dist-packages/pkg_resources/init.py", line 656, in run_script
self.require(requires)[0].run_script(script_name, ns)
File "/usr/lib/python3/dist-packages/pkg_resources/init.py", line 1453, in run_script
exec(code, namespace, namespace)
File "/usr/local/lib/python3.10/dist-packages/ptf-0.9.3-py3.10.egg/EGG-INFO/scripts/ptf", line 859, in
ptf.dataplane_instance.port_add(ifname, device, port)
File "/usr/local/lib/python3.10/dist-packages/ptf-0.9.3-py3.10.egg/ptf/dataplane.py", line 682, in port_add
self.ports[port_id] = self.dppclass(
File "/usr/local/lib/python3.10/dist-packages/ptf-0.9.3-py3.10.egg/ptf/dataplane.py", line 145, in init
self.socket.bind((interface_name, self.ETH_P_ALL))
OSError: [Errno 19] No such device

Add link to public prices of SRAM parts to cost of memory article

This is the article that should be edited: https://github.com/jafingerhut/p4-guide/blob/master/docs/cost-of-high-speed-storage.md

Ben Lewis pointed out this public source for prices of SRAM parts: https://uk.farnell.com/w/c/semiconductors-ics/memory/sram/prl/results?sort=P_PRICE%7C1

There is probably a similar one in US dollars, too, but if not easily found, just use that one and the current US dollars / British pound exchange rate, and mention the exchange rate used in the article.

error compiling a customised demo1 p4 program

Hi Andy,

i am not sure if this is the right forum or procedure to ask for help. Please fee free to ignore if i am posting in wrong forum!!

I am seeing an compilation error like below after i tried creating a p4 from ground up. There were so many other errors which were eithe syntactical or something i could solve on my own. This one seemed to be something needs another pair of eyes.

p4c --target bmv2 --arch v1model Trial.p4
Trial.p4(124): [--Werror=type-error] error: main: Cannot unify functions with different number of arguments: function(hdr, meta) to function(hdr, meta, standard_metadata)
) main;
^^^^

`#include <core.p4>
#include <v1model.p4>
header Ethernet_f {
bit<48> dstAddr;
bit<48> srcAddr;
bit<16> etherType;
}
header Ipv4_p {
bit<4> version;
bit<4> ihl;
bit<8> diffServ;
bit<16> totalLength;
bit<16> identification;
bit<3> flags;
bit<13> fragmnetOffset;
bit<8> ttl;
bit<8> protocol;
bit<16> headerChecksum;
bit<32> srcIp;
bit<32> dstIp;
}
struct headers {
Ethernet_f ethernet;
Ipv4_p ipv4;
}
parser programmableParser(packet_in packet, out headers hdr, inout standard_metadata_t meta)
{
state start {
transition parse_ethernet;
}
state parse_ethernet {
packet.extract(hdr.ethernet);
transition select(hdr.ethernet.etherType){
0x8100 : parse_ipv4;
default : accept;
}

}
state parse_ipv4  {
    packet.extract(hdr.ipv4);
    transition accept;
}

}
control ipmatchAction(inout headers hdr, inout standard_metadata_t meta)
{
action drop(){
mark_to_drop(meta);
}
action set_port(bit<9> port , bit<48>dmac,bit<48>smac){
meta.egress_spec = port;
hdr.ethernet.srcAddr = smac;
hdr.ethernet.dstAddr = dmac;
hdr.ipv4.ttl= hdr.ipv4.ttl-1;
}
table ipv4_lpm{
key = {
hdr.ipv4.dstIp : lpm ;

    }
    actions = {

        set_port;
        drop;
    }
    default_action = drop;
}

apply {
    ipv4_lpm.apply();
}

}
control MyEgress(inout headers hdr, inout standard_metadata_t meta) {
apply { }
}
control deparseImp(packet_out packet,in headers hdr)
{
apply {
packet.emit(hdr.ethernet);
packet.emit(hdr.ipv4);
}
}
control verifyChecksum(inout headers hdr, inout standard_metadata_t meta) {
apply {
verify_checksum(hdr.ipv4.isValid() && hdr.ipv4.ihl == 5,
{ hdr.ipv4.version,
hdr.ipv4.ihl,
hdr.ipv4.diffServ,
hdr.ipv4.totalLength,
hdr.ipv4.identification,
hdr.ipv4.flags,
hdr.ipv4.fragmnetOffset,
hdr.ipv4.ttl,
hdr.ipv4.protocol,
hdr.ipv4.srcIp,
hdr.ipv4.dstIp },
hdr.ipv4.headerChecksum, HashAlgorithm.csum16);
}
}

control updateChecksum(inout headers hdr, inout standard_metadata_t meta) {
apply {
update_checksum(hdr.ipv4.isValid() && hdr.ipv4.ihl == 5,
{ hdr.ipv4.version,
hdr.ipv4.ihl,
hdr.ipv4.diffServ,
hdr.ipv4.totalLength,
hdr.ipv4.identification,
hdr.ipv4.flags,
hdr.ipv4.fragmnetOffset,
hdr.ipv4.ttl,
hdr.ipv4.protocol,
hdr.ipv4.srcIp,
hdr.ipv4.dstIp },
hdr.ipv4.headerChecksum, HashAlgorithm.csum16);
}
}

V1Switch(programmableParser(),
verifyChecksum(),
ipmatchAction(),
MyEgress(),
updateChecksum(),
deparseImp()
) main;
`

TCP options Deparsing using emit when using Header_union

Hello,

I wanted to parse the tcp options in a packet and modify the option fields like timestamps and egress the packet out of the P4 BMV2 version switch port. I was trying to use header_union to club all the options fileld headers and following the options parser github page as a reference https://github.com/jafingerhut/p4-guide/blob/master/tcp-options-parser/tcp-options-parser.p4. I am successful to parse the options and perform the actions needed on the option field. But, when i am trying to deparse the tcp options using "emit", It only deparse the one header of the header_union and leave the rest of the headers which needs to be deparsed. I am just wondering if i am doing wrong to deparse or its limitation of using header_union in the p4?

For instance, in the example mentioned, the below were the tcp option header fields in the header_union.
Tcp_option_end_h end;
Tcp_option_nop_h nop;
Tcp_option_ss_h ss;
Tcp_option_s_h s;
Tcp_option_sack_h sack;

Is there a way to use "emit" to deparse all those headers before sending the packet out of the switch?

thanks for the time

Bmv2 queue size modification

Hello there,
I am working on the ECN problem from the tutorials page (reference). I would like to change the queue size of the switch. I tried changing it through the accompanied topology.json (modified the run_exercise.py accordingly). I can see the queue size to be changed using tc -s class show dev eth on the switch terminal but it seems like that is over ridden by the bmv2 and it uses it's default queue size (64 packets) everytime.
My question: how can I change the bmv2 queue size (hardcoded/programmatic)?

TCP option parsing example uses wrong formats for TCP options

I do not recall what reference I might have been using (if any) for the format of TCP options when I wrote the P4 code in https://github.com/jafingerhut/p4-guide/tree/master/tcp-options-parser, but on 2021-Dec-22 Rob Starr on the p4-lang Slack channel pointed out that several of the options formats do not match their definitions from the relevant RFCs, such as:

I am open to someone else submitting fixes for these example programs if they are interested. Happy to keep your name as the author and include your file in this repo, or to link to your published copy from my repo if you prefer.

Note that these TCP options parsing examples were created more as a proof of concept that it is possible within the features of the P4_16 language to parse TCP options. That does not mean that this is a practical thing to do, necessarily, nor that this P4 code will compile on your favorite high speed P4-programmable target device, because some of them probably cannot compile this code (even if it were corrected).

how can i solve this problem?

I have a question about how to transmit the replicated data packets in the router to the controller for analysis. I hope you can help me answer it. Thank you

Add ipv6_bytes() to base_test.py

def ipv6_to_bytes(addr):
""" Convert IPv6 address to a bytearray. """
return socket.inet_pton(socket.AF_INET6, addr)

Also ipv4_to_bytes can change to

def ipv4_to_bytes(addr):
""" Convert IPv4 address to a bytearray. """
return socket.inet_pton(socket.AF_INET, addr)

I would prefer that typing closing brace behave like c-mode's c-electric-brace

At least in my use of p4_14-mode and p4_16-mode, typing a closing brace } on a line by itself leaves it at the current indent level, rather than auto-'outdenting' it like c-mode does. In c-mode this occurs because the key } is bound to the command c-electric-brace. I have tried an experiment of doing M-x c-electric-brace in a buffer that was in p4_16-mode, but it didn't have the same effect, so that command probably depends upon c-mode or c++-mode in some way.

Add parser value sets to p4-16-allowed-constructs

This feature was added to the P4_16 language spec, I believe after the v1.0.0 release, before the v1.1.0 release.

Should also double-check all of the places where constructs are documented as allowed vs. need-not-be-supported in the latest P4_16 language spec to see if anything has changed since I wrote the p4-16-allowed-constructs files.

Sysrepo : error with make

Hi,
I need your help
I'm installing P4 runtime while using the steps existing in the file install-p4dev-p4runtime.sh
link : https://github.com/jafingerhut/p4-guide/blob/master/bin/install-p4dev-p4runtime.sh
when installing the sysrepo with the following commands:
git clone https://github.com/sysrepo/sysrepo.git
cd sysrepo
git checkout v0.7.5
mkdir build
cd build
cmake -DCMAKE_BUILD_TYPE=Release -DBUILD_EXAMPLES=Off -DCALL_TARGET_BINS_DIRECTLY=Off ..

When I use the make command it gives me an error us you can see in attached file
error_sysrepo

Thank you so much for your help

Issue in Ubuntu 20.04

In Ubuntu 20.04, the simple_switch_CLI doesn't work. it ends with following error

Traceback (most recent call last):
  File "/usr/local/bin/simple_switch_CLI", line 29, in <module>
    import sswitch_CLI
ImportError: No module named sswitch_CLI

Any idea why ?

Compilation error

screenshot from 2018-11-14 18-38-31
I am a newbie to p4c while going through you repo instruction for installation of p4 I run the script install-p4dev-runtime.sh and after it try to run demo1.p4_16.p4 but getting an error message no file input as in the attached screenshot. Kindly help me in resolving the problem

Add hex min and max to match-range-using-tcam

The current Python code does not accept a hex number for min and max with match-range-using-tcam.

One way to fix the issue is to add this function at the top of the code.

def auto_int(x):
        return int(x, 0)

Then changing type=int to type=auto_int where min and max are parsed.

Then this use of the Python code works.

python range-to-tcam-entries.py --bit-width 16 --min 0x0800 --max 0x0806

Issue in log file for bmv2 switch

I am trying to run a bmv2 based sitch using simple_switch_grpc. The command for starting the switch is

simple_switch_grpc --device-id 1 -i 1@p0l0-eth1 -i 2@p0l0-eth2 -i 3@p0l0-eth3 -i 4@p0l0-eth4 -i 5@p0l0-eth5 -i 6@p0l0-eth6 -i 7@p0l0-eth7 -i 8@p0l0-eth8 --thrift-port 52765 --nanolog ipc:///tmp/bmv2-p0l0-nanolog.ipc --debugger-addr ipc:///tmp/bmv2-p0l0-debug.ipc -Lwarn --no-p4 -- --cpu-port 255 --grpc-server-addr 127.0.0.1:60000 --log-file p0l0.log

But I am getting the error message :

unrecognised option '--log-file'

I have compiled the simple_switch_grps with --enable-debugger option. But still it's not working for the log file. Can anyone please help me?

Not able to run tutorial exercises

Recently started working on P4, I tried the following:

sudo apt install git
git clone https://github.com/jafingerhut/p4-guide
./p4-guide/bin/install-p4dev-v4.sh |& tee log.txt

And then to start working on tutorials, I did the following:
$ git clone https://github.com/p4lang/tutorials
$ cd tutorials/exercises/basic
$ cp solution/basic.p4 basic.p4
$ make run

I get the following error message:
root@GGNLABDTE00059:~/tutorials/exercises/basic# make run
mkdir -p build pcaps logs
p4c-bm2-ss --p4v 16 --p4runtime-files build/basic.p4.p4info.txt -o build/basic.json basic.p4
sudo python3 ../../utils/run_exercise.py -t pod-topo/topology.json -j build/basic.json -b simple_switch_grpc
Traceback (most recent call last):
File "../../utils/run_exercise.py", line 28, in
import p4runtime_lib.simple_controller
File "/root/tutorials/utils/p4runtime_lib/simple_controller.py", line 22, in
from p4.config.v1 import p4info_pb2
ModuleNotFoundError: No module named 'p4.config'
../../utils/Makefile:35: recipe for target 'run' failed
make: *** [run] Error 1

What am I missing?

p4info not generated by p4c

I installed p4c using install-p4dev-p4runtime.sh script.
Now when I am compiling basic.p4 (from p4lang/tutorials/exercises) program using command:

p4@p4-VirtualBox:~/p4-setup/exercises/basic$ p4c --target bmv2 --arch v1model --p4runtime-files basic.p4rt.txt basic.p4

The .json and .p4rt file are generated but no build directory or the p4info file (basic.p4.p4info.txt) is being generated when the compilation ends. I tried the same command with p4c-bm2-ss too, but no results.

What can be done in this case?

read table entries using the P4Runtime API

In README-p4runtime.me, you write:

Let me know if you find a way to read table entries using the P4Runtime API via
the interactive Python session created above. There must be a way.

You can retrieve table entries with the table_dump_data method:

>>> h.table_dump_data('ipv4_da_lpm')
[table_id: 33571396
match {
  field_id: 1
  lpm {
    value: "\n\001\000\001"
    prefix_len: 32
  }
}
action {
  action {
    action_id: 16798847
    params {
      param_id: 1
      value: "\000\000\000:"
    }
  }
}
, table_id: 33571396
match {
  field_id: 1
  lpm {
    value: "\n\001\000\310"
    prefix_len: 32
  }
}
action {
  action {
    action_id: 16798847
    params {
      param_id: 1
      value: "\000\000\000Q"
    }
  }
}
]

However, this is not equivalent with table_dump ipv4_da_lpm of simple_switch_CLI, since it seems we cannot query the tables' default action via grpc.

Thank you for p4-guide, it is very useful.

py3localpath.py prints incomplete output

I was running the script install-p4dev-v6, which ran fine until it stopped without doing anything. The last output recorded is this:

...
py3localpath.py debug output. sys.path contains:
/home/rui/phd/p4-guide/bin
/usr/lib/python38.zip
/usr/lib/python3.8
/usr/lib/python3.8/lib-dynload
/home/rui/.local/lib/python3.8/site-packages
/usr/local/lib/python3.8/dist-packages
/usr/local/lib/python3.8/dist-packages/thrift-0.13.0-py3.8.egg
/usr/lib/python3/dist-packages

I then identified the culprit line:

PY3LOCALPATH=`${THIS_SCRIPT_DIR_ABSOLUTE}/py3localpath.py`

The return value of this execution was 1, and since the set -e option is set, the script aborts on non-zero returns.

After examining py3localpath.py, I discovered that it had a few more things to say, but, in order to display them, I had to edit the prints to include file=sys.stderr. Then the script started divulging the problem correctly:

py3localpath.py debug output. sys.path contains:
... (same list as above)
Found 2 matching entries in Python3 sys.path instead of 1: ['/usr/local/lib/python3.8/dist-packages', '/usr/local/lib/python3.8/dist-packages/thrift-0.13.0-py3.8.egg']

(P.S. -- Is it safe to simply edit py3localpath.py to take '/usr/local/lib/python3.8/dist-packages' and reject the other entry?)

Consider adding script to build behavioral-model simple_switch_grpc

The script would be most useful if there is a straightforward way to also update the README examples of adding table entries to use P4Runtime to add table entries, too, e.g. perhaps from a Python interactive session? Perhaps a few Python functions written specifically to make it easier to add/delete/show table entries using P4Runtime API?

See the simple_switch_grpc README here: https://github.com/p4lang/behavioral-model/tree/master/targets/simple_switch_grpc

demo1 - simple_switch_CLI

It could be my fault, but in demo1-Running I always have to add "ingress." or "egress." to the CLI-commands (e.g. "table_add ingress.ipv4_da_lpm ingress.set_l2ptr 10.1.0.1/32 => 58"), otherwise I get an error ("Invalid table name (ipv4_da_lpm)")

[Question] P4 standard headers file

Hi,
is it possible to create a single P4 file template containing the common standard headers that P4 is actually able to parse? for example, containing:

  • L2 headers
  • IPv4 headers
  • IPv6 headers
  • TCP headers
  • UDP headers
  • ...

This way, whenever someone has to deal with standard protocols it's just a matter of 'copy-paste'.

Unable to send packets on veth interfaces

I am trying to run the following codes , but getting an error all the time:

sudo scapy

fwd_pkt1=Ether() / IP(dst='10.1.0.1') / TCP(sport=5793, dport=80)
drop_pkt1=Ether() / IP(dst='10.1.0.34') / TCP(sport=5793, dport=80)

# Send packet at layer2, specifying interface
sendp(fwd_pkt1, iface="veth2")
sendp(drop_pkt1, iface="veth2")

fwd_pkt2=Ether() / IP(dst='10.1.0.1') / TCP(sport=5793, dport=80) / Raw('The quick brown fox jumped over the lazy dog.')
sendp(fwd_pkt2, iface="veth2")

I am getting the following errors , lemme know , where I am going wrong ?:

sendp(fwd_pkt1, iface="veth2") Traceback (most recent call last):
File "", line 1, in
File "/usr/lib/python2.7/dist-packages/scapy/sendrecv.py", line 278, in sendp
return __gen_send(conf.L2socket(iface=iface, *args, **kargs), x, inter=inter, loop=loop, count=count,
File "/usr/lib/python2.7/dist-packages/scapy/arch/linux.py", line 432, in init
set_promisc(self.ins, self.iface)
File "/usr/lib/python2.7/dist-packages/scapy/arch/linux.py", line 160, in set_promisc
mreq = struct.pack("IHH8s", get_if_index(iff), PACKET_MR_PROMISC, 0, "")
File "/usr/lib/python2.7/dist-packages/scapy/arch/linux.py", line 292, in get_if_index
return int(struct.unpack("I",get_if(iff, SIOCGIFINDEX)[16:20])[0])
File "/usr/lib/python2.7/dist-packages/scapy/arch/common.py", line 19, in get_if
ifreq = ioctl(sck, cmd, struct.pack("16s16x", iff))
IOError: [Errno 19] No such device

ImportError cannot import name 'cygrpc' when running runptf.sh in demo1

Environment
python 3.8
grpcio 1.47.0

The error when running runptf.sh in demo1/

import grpc
  File "/usr/lib/python3/dist-packages/grpc/__init__.py", line 22, in <module>
    from grpc._cython import cygrpc as _cygrpc
ImportError: cannot import name 'cygrpc'

I also tried running runptf.sh with grpcio==1.27.2 as suggested here, but the error remains. Any suggestions?

AttributeError: type object 'int' has no attribute 'from_bytes'

When I run demo1 test script "runptf.sh", I met the following trouble:
2021-05-24 16:08:39,094 - root - INFO - Importing platform: eth
2021-05-24 16:08:39,095 - root - DEBUG - Configuration: {'xunit_dir': 'xunit', 'disable_ipv6': False, 'minsize': 0, 'list_test_names': False, 'test_file': None, 'test_spec': '', 'allow_user': False, 'test_order_seed': 2746, 'default_negative_timeout': 0.1, 'platform': 'eth', 'log_dir': None, 'xunit': False, 'disable_erspan': False, 'device_sockets': [], 'disable_geneve': False, 'socket_recv_size': 4096, 'profile': False, 'default_timeout': 2.0, 'platform_args': None, 'relax': False, 'disable_rocev2': False, 'random_seed': None, 'interfaces': [(0, 0, 'veth1'), (0, 1, 'veth3'), (0, 2, 'veth5'), (0, 3, 'veth7'), (0, 4, 'veth9'), (0, 5, 'veth11'), (0, 6, 'veth13'), (0, 7, 'veth15')], 'test_case_timeout': None, 'port_map': {(0, 1): 'veth3', (0, 0): 'veth1', (0, 7): 'veth15', (0, 6): 'veth13', (0, 5): 'veth11', (0, 4): 'veth9', (0, 3): 'veth7', (0, 2): 'veth5'}, 'disable_vxlan': False, 'disable_nvgre': False, 'qlen': 100, 'test_order': 'default', 'profile_file': 'profile.out', 'fail_skipped': False, 'test_params': "grpcaddr='localhost:9559';p4info='demo1.p4_16.p4rt.txt';config='demo1.p4_16.json'", 'test_dir': 'ptf', 'list': False, 'platform_dir': '/usr/local/lib/python2.7/dist-packages/ptf-0.9.1-py2.7.egg/ptf/platforms', 'disable_igmp': False, 'disable_mpls': False, 'debug': 'verbose', 'log_file': 'ptf.log', 'failfast': False}
2021-05-24 16:08:39,095 - root - INFO - port map: {(0, 1): 'veth3', (0, 0): 'veth1', (0, 7): 'veth15', (0, 6): 'veth13', (0, 5): 'veth11', (0, 4): 'veth9', (0, 3): 'veth7', (0, 2): 'veth5'}
2021-05-24 16:08:39,095 - root - INFO - Autogen random seed: 67424784
2021-05-24 16:08:39,097 - root - INFO - *** TEST RUN START: Mon May 24 16:08:39 2021
demo1.FwdTest ... ERROR

======================================================================
ERROR: demo1.FwdTest

Traceback (most recent call last):
File "/home/ylj/xjy/p4-guide/testlib/base_test.py", line 1009, in handle
return f(*args, **kwargs)
File "ptf/demo1.py", line 145, in runTest
self.table_add(self.key_ipv4_da_lpm(ip_dst_addr, 32),
File "ptf/demo1.py", line 100, in key_ipv4_da_lpm
bt.ipv4_to_int(ipv4_addr_string), prefix_len)])
File "/home/ylj/xjy/p4-guide/testlib/base_test.py", line 103, in ipv4_to_int
return int.from_bytes(bytes(bytes_), byteorder='big')
AttributeError: type object 'int' has no attribute 'from_bytes'


Ran 1 test in 0.124s

FAILED (errors=1)
demo1.DupEntryTest ... ERROR

======================================================================
ERROR: demo1.DupEntryTest

Traceback (most recent call last):
File "/home/ylj/xjy/p4-guide/testlib/base_test.py", line 1009, in handle
return f(*args, **kwargs)
File "ptf/demo1.py", line 236, in runTest
add_entry_once()
File "ptf/demo1.py", line 233, in add_entry_once
self.table_add(self.key_ipv4_da_lpm(ip_dst_addr, 32),
File "ptf/demo1.py", line 100, in key_ipv4_da_lpm
bt.ipv4_to_int(ipv4_addr_string), prefix_len)])
File "/home/ylj/xjy/p4-guide/testlib/base_test.py", line 103, in ipv4_to_int
return int.from_bytes(bytes(bytes_), byteorder='big')
AttributeError: type object 'int' has no attribute 'from_bytes'


Ran 1 test in 0.015s

FAILED (errors=1)
demo1.PrefixLen0Test ... ERROR

======================================================================
ERROR: demo1.PrefixLen0Test

Traceback (most recent call last):
File "/home/ylj/xjy/p4-guide/testlib/base_test.py", line 1009, in handle
return f(*args, **kwargs)
File "ptf/demo1.py", line 201, in runTest
e['prefix_len']),
File "ptf/demo1.py", line 100, in key_ipv4_da_lpm
bt.ipv4_to_int(ipv4_addr_string), prefix_len)])
File "/home/ylj/xjy/p4-guide/testlib/base_test.py", line 103, in ipv4_to_int
return int.from_bytes(bytes(bytes_), byteorder='big')
AttributeError: type object 'int' has no attribute 'from_bytes'


Ran 1 test in 0.015s

FAILED (errors=1)
()


ATTENTION: SOME TESTS DID NOT PASS!!!
()
The following tests errored:
FwdTest, DupEntryTest, PrefixLen0Test
()


make run error creating error interface

here I have a problem when I change the topology, I change the topology to a mesh topology and there are 2 hosts with 5 switches, when I set the link there is an error like this

File "../../utils/run_exercise.py", line 387, in
exercise.run_exercise()
File "../../utils/run_exercise.py", line 195, in run_exercise
self.create_network()
File "../../utils/run_exercise.py", line 260, in create_network
controller = None)
File "/usr/local/lib/python3.6/dist-packages/mininet/net.py", line 178, in init
self.build()
File "/usr/local/lib/python3.6/dist-packages/mininet/net.py", line 508, in build
self.buildFromTopo( self.topo )
File "/usr/local/lib/python3.6/dist-packages/mininet/net.py", line 495, in buildFromTopo
self.addLink( **params )
File "/usr/local/lib/python3.6/dist-packages/mininet/net.py", line 406, in addLink
link = cls( node1, node2, **options )
File "/usr/local/lib/python3.6/dist-packages/mininet/link.py", line 568, in init
Link.init( self, *args, **kwargs)
File "/usr/local/lib/python3.6/dist-packages/mininet/link.py", line 457, in init
node1, node2, deleteIntfs=False )
File "/usr/local/lib/python3.6/dist-packages/mininet/link.py", line 502, in makeIntfPair
deleteIntfs=deleteIntfs )
File "/usr/local/lib/python3.6/dist-packages/mininet/util.py", line 271, in makeIntfPair
( intf1, intf2, cmdOutput ) )
Exception: Error creating interface pair (s4-eth1,s5-eth4): RTNETLINK answers: File exists

../../utils/Makefile:35: recipe for target 'run' failed
make: *** [run] Error 1

Adding veth delete option.

Great job with this. Did you consider adding a separate script to delete the interfaces setup with veth_setup.sh, or making that a command line option? There may be scenarios in which it is easier than doing things manually or rebooting. It would only require a few modifications to the setup script.

[Question]How to write const entries for range match?

Hi @jafingerhut, I have a question, how to write const entries for range match?

139     table test_range {
140         key = {
141             hdr.ipv4.total_len: range;
142         }
143 
144         actions = {hit;miss;}
145         const entries = {
146             (16w0x800):miss();
147         }
148     }

It can be compiled successfully, but cannot be added, can you give me a help?

AttributeError: P4RuntimeTest instance has no attribute 'fail'

I am following steps mentioned in p4-guide/demo1/README-p4runtime.md and on executing line h.setUp(my_dev1_addr, 'demo1.p4_16.p4rt.txt')
I get this error:

>>> h.setUp(my_dev1_addr, 'demo1.p4_16.p4rt.txt')
Importing p4info proto from demo1.p4_16.p4rt.txt
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "base_test.py", line 270, in setUp
    self.set_up_stream()
  File "base_test.py", line 324, in set_up_stream
    self.handshake()
  File "base_test.py", line 340, in handshake
    self.fail("Failed to establish handshake")
AttributeError: P4RuntimeTest instance has no attribute 'fail'

What can be done to solve this?

Problem in register declaration

Hello there,
I am trying to extend the ECN code from P4 tutorials. I am declaring two new registers in MyIngress control block. I am receiving this error although I am declaring the register properly. Help!!

ecn.txt
image

Question: Does it make sense in P4_16 to have actions invoked by a table with direction `out` or `inout` parameters?

Does it make sense in P4_16 to have actions invoked by a table with direction out or inout parameters?

Does it even make sense to have in direction parameters to an action invoked by a table?

If so, what is use case that makes this helpful to do?

Does anyone actually do this in P4_16 programs?

If so, what for? Can it easily be rewritten not to use parameters with directions?

For an inout direction parameter of an action invoked by a table, is that effectively just about the same as reading and writing to the value of some variable in the surrounding lexical scope, as long as there was no aliasing going on?

Suggestion: use officially supported versions of protobuf / gRPC in installation scripts

Looking at one script (https://github.com/jafingerhut/p4-guide/blob/master/bin/install-p4dev-p4runtime.sh), I realized that it was still installing the older versions of protobuf (3.2.0) and gRPC (1.3.2). To avoid confusion, I suggest moving to protobuf 3.6.1 and gRPC 1.17.2, which is the versions currently "officially" supported by p4lang software.

I also suggest installing the same versions for the Python packages. The script currently defaults to some version which depends on the distribution. The suggestion can be achieved with:

sudo pip install protobuf==3.6.1
sudo pip install grpcio==1.17.2

Update README-header-stacks.md with resolution

It explains the differences between P4_14, P4_16, and BMv2 that used to exist, but that is over a year ago now, and it would be good to have a resolution section near the top explaining why the document was written, and a very brief summary of which of the alternatives was actually implemented, with pointers to the changes made.

Conditional execution in actions is not supported

salam
I have add condition in the ''set_l2ptr'' action as you can see bellow
--- I use the condition to count the received SYN packets

direct_counter(CounterType.packets) ipv4_da_lpm_stats;
action set_l2ptr(bit<32> l2ptr) {

  if (hdr.tcp.flags == 02){

    ipv4_da_lpm_stats.count();}
    meta.fwd_metadata.l2ptr = l2ptr;
}

P4_program.txt

when compiling It gives me the following error

SYN_defense.p4(120): error: MethodCallStatement: Conditional execution in actions is not supported on this target
ipv4_da_lpm_stats.count();}
^^^^^^^^^^^^^^^^^^^^^^^^^
As I verify in previous issues #379, #644 ; now the conditions are supported in actions but it gives me error

Thank you for help

error_conditional_execution in action is not supported

Error while installing Thrift 0.11.0

While installing Behavioral-model on ubuntu 18.04 Machine, I am facing an error while installing Thrift v0.11.0. I am installing using the script 'install-p4dev-v2.sh'. I have attached a screenshot to this issue. All the dependencies are installed while installing Thrift. The log says

libtool: link: g++ -Wall -Wextra -pedantic -g -O2 -o .libs/concurrency_test concurrency/Tests.o -L/usr/lib/x86_64-linux-gnu ../../../lib/cpp/.libs/libthrift.so -lrt -lpthread
../../../lib/cpp/.libs/libthrift.so: undefined reference to `OPENSSL_sk_pop_free'

../../../lib/cpp/.libs/libthrift.so: undefined reference to `OPENSSL_sk_value'

../../../lib/cpp/.libs/libthrift.so: undefined reference to `OPENSSL_sk_num'

../../../lib/cpp/.libs/libthrift.so: undefined reference to `OPENSSL_init_ssl'

../../../lib/cpp/.libs/libthrift.so: undefined reference to `OPENSSL_init_crypto'

../../../lib/cpp/.libs/libthrift.so: undefined reference to `TLS_method'

../../../lib/cpp/.libs/libthrift.so: undefined reference to `SSL_CTX_set_options'

collect2: error: ld returned 1 exit status
Makefile:1202: recipe for target 'concurrency_test' failed
make[5]: *** [concurrency_test] Error 1
make[5]: *** Waiting for unfinished jobs....

If you can help me resolve this then it will be very great of you.

Screenshot from 2021-08-26 16-32-20

Can not complied with the optimization flags

HI,

Based on the document : https://github.com/p4lang/behavioral-model/blob/main/docs/performance.md.

If we want our bmv2 instance to have better performance, we need to compile it with extra flags:
'CXXFLAGS=-g -O3' 'CFLAGS=-g -O3' --disable-logging-macros --disable-elogger( ob bmv2 configure file).

I tried the installation script on clean ubuntu 20.04 - std and ubuntu 18.04 - std images. However, none of them can compile with such flags successfully.

Based on my situation, I need a simple_swtich_grpc instance run on VM or bare metal machine with as best performance as possible.

Is there any way out ?

Best Regards,

Error: Table has no action my_drop

I used install-p4dev-p4runtime.sh script to build behavioral model, p4c compiler and simple_switch.
Then I compiled the demo1 program and ran the simple_switch. Now, when I am trying to add table entries using simple_switch_CLI, it gives me these errors.

Control utility for runtime P4 table manipulation
RuntimeCmd: table_set_default ipv4_da_lpm my_drop
Error: Table ipv4_da_lpm has no action my_drop
RuntimeCmd: table_set_default mac_da my_drop
Error: Table mac_da has no action my_drop
RuntimeCmd: table_set_default send_frame my_drop
Error: Table send_frame has no action my_drop
RuntimeCmd: 

I checked the demo1 p4 program and it does have a definition for my_drop action. Still, I am getting this error. Can I get some help as to how this error can be resolved?

Consider adding notes on ways to handle variable-length headers

General limitation in P4_14 and P4_16 language specs - you can define headers with at most one variable-length field at the end. You can remove such headers, or preserve them in the output packet (optionally modifying one or more fixed-length fields in such headers, but the variable-length part cannot be modified or read without language extensions). There is no way without language extensions to add a header with a variable-length field to a packet, and initialize the contents of the variable-length field.

One general technique that is appropriate in some cases - define multiple fixed length headers, one for each of the sizes you want your P4 program to handle. This can be useful both for parsing, and for adding new headers to packets.

Another is header stacks.

See this email message and its follow-up messages for some more details: http://lists.p4.org/pipermail/p4-dev_lists.p4.org/2018-September/003661.html

sudo: p4c command not found

I used install-p4dev-p4runtime.sh script to make the p4c installation. Furthermore, as directed I copied the contents of p4setup.bash to both my .bashrc and my .profile file.

Now when I give command as:
sudo p4c --target bmv2 --arch v1model --p4runtime-files demo1.p4_16.p4rt.txt demo1.p4_16.p4

It shows me error as:
sudo: p4c: command not found
But, on removing sudo and giving command:
p4c --target bmv2 --arch v1model --p4runtime-files demo1.p4_16.p4rt.txt demo1.p4_16.p4
compilation works fine.

I don't know whether it's some error or some lack of Linux knowledge from my side.

install-p4dev-v5.sh "The unauthenticated git protocol on port 9418 is no longer supported"

First of all thanks for your ongoing effort and the nice v5 of your install-p4dev script! The speedup thanks to the package-based installation is really great and most appreciated! install-p4dev-v5.sh used to work flawlessly up until some days ago, but now it seams like GitHub does not allow unauthenticated clones anymore and mininet cannot be installed using git clone git://github.com/mininet/mininet anymore...

Successfully installed grpcio-1.44.0 psutil-5.9.0 ptf-0.9.3 scapy-2.4.5 six-1.16.0
+ echo ------------------------------------------------------------
------------------------------------------------------------
+ echo 'Installing Mininet - not necessary to run P4 programs, but useful if'
Installing Mininet - not necessary to run P4 programs, but useful if
+ echo 'you want to run tutorials from https://github.com/p4lang/tutorials'
you want to run tutorials from https://github.com/p4lang/tutorials
+ echo repository.
repository.
+ echo 'start install mininet:'
start install mininet:
+ set -x
+ date
Fri Mar 18 15:00:33 UTC 2022
+ git clone git://github.com/mininet/mininet mininet
Cloning into 'mininet'...
fatal: remote error:
  The unauthenticated git protocol on port 9418 is no longer supported.
Please see https://github.blog/2021-09-01-improving-git-protocol-security-github/ for more information.
p4@prona-image-test-v5-again:~$

seams to be easy to fix, as I only needed to change line 241 from git: to https://

p4@prona-image-test-v5-again:~/p4-guide$ diff bin/install-p4dev-v5.sh.patched bin/install-p4dev-v5.sh.old
241c241
< git clone https://github.com/mininet/mininet mininet
---
> git clone git://github.com/mininet/mininet mininet
p4@prona-image-test-v5-again:~/p4-guide$

afterwards. install-p4dev-v5.sh went through without errors again.

Thanks!

Sebastian

Errors while running CTest.

When I test my installation, that is,

$ cd p4c/build

$ make check

and I get the result of failure, like the following,

image

and I have installed the dependencies required by ebpf, how can I solve it?
I will be deeply grateful for your reply!

install correctly, but make run error. ImportError: No module named grpc

I am a Chinese user. I installed the P4 environment with the install-p4dev-p4runtime.sh. because of the GFW, the first time grpc install failed. Then through proxy I installed grpc correctly, and the others dependent it. but when i run "make run" command in "basic" folder, an error occurs.
mkdir -p build pcaps logs sudo python ../../utils/run_exercise.py -t topology.json -b simple_switch_grpc [sudo] password for daniel: Traceback (most recent call last): File "../../utils/run_exercise.py", line 33, in <module> import p4runtime_lib.simple_controller File "/home/daniel/workspace/p4/tutorials/utils/p4runtime_lib/simple_controller.py", line 22, in <module> import bmv2 File "/home/daniel/workspace/p4/tutorials/utils/p4runtime_lib/bmv2.py", line 15, in <module> from switch import SwitchConnection File "/home/daniel/workspace/p4/tutorials/utils/p4runtime_lib/switch.py", line 19, in <module> import grpc ImportError: No module named grpc ../../utils/Makefile:27: recipe for target 'run' failed make: *** [run] Error 1
my OS is ubuntu16.04. So what's the problem?

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.