Coder Social home page Coder Social logo

p4runtime-go-client's Introduction

p4runtime-go-client

Go client for P4Runtime

This project is still a work in progress. We make no guarantee for the stability of the API and may modify existing functions in the client API. We welcome feedback and contributions!.

For a good place to start, check out the l2_switch example.

p4runtime-go-client's People

Contributors

antoninbas avatar dependabot[bot] avatar emanuelegallone avatar gcgirish avatar osinstom avatar rickycraft avatar stolsma avatar venkateshpnv avatar vishala-r 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

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

p4runtime-go-client's Issues

Adding context support to Client

Right now when creating a Client is required a stopCh to manage proper cleanup of the goroutine.
func (c *Client) Run(stopCh <-chan struct{},arbitrationCh chan<- bool,messageCh chan<- *p4_v1.StreamMessageResponse)
I'm new to go, but from what i've seen substituting it with context.Context is a more stardard way to do it. It should be a minor change.

Packet-out using P4Runtime Client?

The streamSendCh isn't exposed to the P4runtime client application. See the Client struct below.

type Client struct {
	ClientOptions
	p4_v1.P4RuntimeClient
	deviceID     uint64
	electionID   p4_v1.Uint128
	p4Info       *p4_config_v1.P4Info
	role         *p4_v1.Role
	streamSendCh chan *p4_v1.StreamMessageRequest
}

Should we expose a new API, for instance SendMessage, in client.go for the client application to send packet-outs or other messages?
Something like below...

func (c *Client) SendMessage(msg *p4_v1.StreamMessageRequest) {
        c.streamSendCh <- msg:
}

Cannot run example/l2_switch successfully

Hello. I'm trying to use this lib to build a controller for both bmv2 and Tofino. Thus, I want to run the example first to know how this lib works. However, I received an RPC error and cannot run l2_switch successfully.

My environment

  • OS: Ubuntu 22.04
  • ARCH: x86_64
  • p4c: 1.2.4.2
  • go: 1.22.2
  • simple_switch_grpc: 1.15.0-6ee70b5e

How I run l2_switch

The command to install go-bindata is not suitable for go 1.22.2, so I install it using go install -a -v github.com/go-bindata/go-bindata/...@latest

I have installed p4c already, so I adjusted the Makefile and compiled p4 code manually:

p4c $(CURDIR)/cmd/l2_switch/l2_switch.p4 -o $(CURDIR)/cmd/l2_switch/l2_switch.out/ -b bmv2 -a v1model --std p4-16 --p4runtime-files $(CURDIR)/cmd/l2_switch/l2_switch.out/p4info.pb.txt

Then I used make bin to compile examples. After that, I run examples in the following way:

> sudo python 1sw_demo.py
*** Creating network
*** Adding hosts:
h1 h2 
*** Adding switches:
s1 
*** Adding links:
(h1, s1) (h2, s1) 
*** Configuring hosts
h1 h2 
*** Starting controller

*** Starting 1 switches
s1 Starting P4 switch s1
simple_switch_grpc -i 1@s1-eth1 -i 2@s1-eth2 --no-p4 --log-console --device-id 0
switch has been started
# Following output is 

> ./bin/l2_switch -bin cmd/l2_switch/l2_switch.out/l2_switch.json -p4info cmd/l2_switch/l2_switch.out/p4info.pb.txt -verbose
INFO[0000] Connecting to server at 127.0.0.1:9559       
INFO[0000] P4Runtime server version is 1.3.0            
INFO[0000] We are the primary client!                   
INFO[0000] Setting forwarding pipe                      
DEBU[0000] Enabling digest 'digest_t'                   
DEBU[0000] Configuring multicast group 171 for broadcast 
FATA[0000] Error when initializing defaults: Cannot configure multicast group 171 for broadcast: rpc error: code = Unknown desc =

And simple_switch_grpc's log is:

> tail -f /tmp/p4s.s1.log
Calling target program-options parser
Adding interface s1-eth1 as port 1
[03:27:55.530] [bmv2] [D] [thread 1187235] Adding interface s1-eth1 as port 1
Adding interface s1-eth2 as port 2
[03:27:55.567] [bmv2] [D] [thread 1187235] Adding interface s1-eth2 as port 2
Server listening on 0.0.0.0:9559
[03:27:55.608] [bmv2] [I] [thread 1187235] Starting Thrift server on port 9090
[03:27:55.608] [bmv2] [I] [thread 1187235] Thrift server was started
[03:28:55.842] [bmv2] [D] [thread 1187954] Set default default entry for table 'tbl_l2_switch89': l2_switch89 - 
[03:28:55.842] [bmv2] [D] [thread 1187954] Set default default entry for table 'IngressImpl.smac': IngressImpl.learn_mac - 
[03:28:55.842] [bmv2] [D] [thread 1187954] Set default default entry for table 'IngressImpl.dmac': IngressImpl.drop - 
[03:28:55.842] [bmv2] [D] [thread 1187954] Set default default entry for table 'tbl_l2_switch39': l2_switch39 - 
[03:28:55.842] [bmv2] [D] [thread 1187954] Set default default entry for table 'tbl_l2_switch41': l2_switch41 - 
[03:28:55.843] [bmv2] [D] [thread 1187954] simple_switch target has been notified of a config swap
[03:28:55.846] [bmv2] [E] [thread 1187958] [P4Runtime] Missing port in multicast group replica

I would like to know where to start to find out why this error occurs. Please give me some advice.

Incorrect numbering of match fields

Giving an example of P4 table:

table table_A {
        key = {
            fieldA          : exact;
            fieldB          : ternary;
            fieldC          : ternary;
            fieldD          : exact;
        }
}

It's recommended to omit "don't care" fields instead of injecting empty fields in the protobuf message. Actually, some P4 software switches (e.g., stratum_bmv2) doesn't accept empty fields at all.

However, if we leave fieldB and fieldC undefined in the []MatchInterface list, the library numbers the match fields incorrectly due to this piece of code:

	for idx, mf := range mfs {
		entry.Match = append(entry.Match, mf.get(uint32(idx+1), c.CanonicalBytestrings))
	}

It results in the following protobuf message, which is incorrect because only field 1 and 4 should be provided:

type: INSERT entity { table_entry { table_id: 49262446 match { field_id: 1 exact { value: "\017\376" } } match { field_id: 2 exact { value: "\001" } } action { action { action_id: 17183246 } } } };

The expected result is:

type: INSERT entity { table_entry { table_id: 49262446 match { field_id: 1 exact { value: "\017\376" } } match { field_id: 4 exact { value: "\001" } } action { action { action_id: 17183246 } } } };

@antoninbas I'm wondering what do you think about possible solutions. I'm thinking about changing the API of NewTableEntry and using map[string]MatchInterface (match field name -> MatchInterface) as mfs (instead of []MatchInterface now). With match field name we can easily get match field ID from P4Info and number fields correctly.

opening up access to client.p4info?

@Antonin, do you have any objections on making the p4info data available outside the client module? If not, any preference on the implementation of that (function returning total p4info var, specific functions returning table etc)?

I want to use your client as building block in a go based p4runtime console with table and action autocompletion etc...

Question regarding p4runtime-go-client/example

I have been using your example from https://github.com/pins/p4runtime-go-client/blob/main/cmd/example/main.go to understand client connection and I was able to get primary connection.
You have a var binPath, what does it refer to?

/ondatra/featureprofiles/feature/p4runtime-go-client/cmd/example# go run main.go
INFO[0000] Connecting to server at 10.49.181.175:50051
INFO[0000] Connected to server at 10.49.181.175:50051
INFO[0000] New p4rt client connection made? 10.49.181.175:50051
INFO[0000] We are the primary client!
INFO[0000] Setting forwarding pipe
FATA[0000] Error when setting forwarding pipe: error when reading binary device config: read /root/go/bin: is a directory

Handle and parse error

Only the top level error is handled today. We need a way to be able to parse the individual update errors in a batch

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.