Git Product home page Git Product logo

Comments (10)

cw299 avatar cw299 commented on July 20, 2024

Is the support of keyword last still under development? simple_switch throws an error message if my p4 program tries to access the largest-index valid instance of a header stack (inside of an action):

terminate called after throwing an instance of 'std::out_of_range'
what(): _Map_base::at

My code looks like:

action my_action() {
    modify_field(stack[last].field, 1);
}

from behavioral-model.

antoninbas avatar antoninbas commented on July 20, 2024

This is still under development. It is likely that I will wait until the new P4 (P4-16) spec comes out so that I can make sure the bmv2 implementation is consistent with the spec.

from behavioral-model.

cw299 avatar cw299 commented on July 20, 2024

I try to access an element of a stack via an index variable. The index variable should be represented by a metadata field. But a metadata field is not an integer data type. Accordingly, the following example won't work:

modify_field(my_metadata.idx, 0);
modify_field(stack[my_metadata.idx].field, 1);

Is there any way to cast an metadata field to an integer?

from behavioral-model.

antoninbas avatar antoninbas commented on July 20, 2024

It would be useful to see what kind of error you are getting.
However, AFAIK:

  • this is disallowed in the P4 language
  • bmv2 does not support it
    In other words, you can only access a header stack element through a compile-time constant.

from behavioral-model.

cw299 avatar cw299 commented on July 20, 2024

The compiler gives the following error:

user@desktop:~/behavioral-model/targets/simple_switch$ p4c-bmv2 simple_switch.p4 --json simple_switch.json
parse error in file /[...]/simple_switch.p4 at line 151 : Syntax error while parsing at token my_metadata (ID)
parse error in file /[...]/simple_switch.p4 at line 151 : Invalid index in array header reference
2 errors during parsing
Interrupting compilation
Error while building HLIR

Background:
I try to process a sequence of MPLS labels that are attached to an incomming packet. The number of MPLS labels is unknown until the Parser counts them and stores the result into a metadata field. The labels themselves are serialized to a separate stack. Each label of the determines an output port. The task of the ingress/egress pipeline is to replicate the packet (maybe by clone* operations) to these ports. However, loops are not allowed in P4, but I need to iterate the stack somehow.

from behavioral-model.

antoninbas avatar antoninbas commented on July 20, 2024

There is probably a workaround that does not involve using a metadata field as an index into the header stack. For example, if you have a reasonable upper bound to the stack depth, you can always hand-write different actions like this:

table mpls_count {
    reads {
        my_metadata.count : exact;
    }
    actions { count_is_1; count_is_2; count_is_3; count_is_4; ...}
}

Obviously this is very verbose, but can be reasonable for up to say 8 mpls labels.
When doing replication, you may want to use the Packet Replication Engine. clone only lets you do one copy per control-flow. But you can always use clone in a "cascading fashion": clone the original packet, then clone the clone, clone the clone of the clone... This works very well if you are allowed to remove (aka pop) the MPLS label after replicating to the port. Actually if you are allowed to do that, this whole thing becomes much easier because all you ever need to look at is stack[0].

from behavioral-model.

cw299 avatar cw299 commented on July 20, 2024

Thanks for your suggestions, great workarounds! The second workaround (cascading cloning) seems to be more flexible. I tried to implement this, but it posed another problem ;-) The Parser seems not to reset it's index counter for the MPLS stack. Please take a look at the following log:

[14:43:21.168] [bmv2] [D] [thread 9330] [0.0] [cxt 0] Processing packet received on port 0
[14:43:21.168] [bmv2] [D] [thread 9330] [0.0] [cxt 0] Parser 'parser': start
[14:43:21.168] [bmv2] [D] [thread 9330] [0.0] [cxt 0] Parser state 'start' has no switch, going to default next state
[14:43:21.168] [bmv2] [T] [thread 9330] Bytes parsed: 0
[14:43:21.168] [bmv2] [D] [thread 9330] [0.0] [cxt 0] Extracting header 'ethernet'
[14:43:21.168] [bmv2] [D] [thread 9330] [0.0] [cxt 0] Parser state 'parse_ethernet' has no switch, going to default next state
[14:43:21.168] [bmv2] [T] [thread 9330] Bytes parsed: 14
[14:43:21.168] [bmv2] [D] [thread 9330] [0.0] [cxt 0] Extracting to header stack 0, next header is 1
[14:43:21.168] [bmv2] [D] [thread 9330] [0.0] [cxt 0] Parser set: setting field (4, 7) from expression, new value is 1
[14:43:21.168] [bmv2] [D] [thread 9330] [0.0] [cxt 0] Parser state 'parse_stack': key is 04
[14:43:21.168] [bmv2] [T] [thread 9330] Bytes parsed: 34
[14:43:21.168] [bmv2] [D] [thread 9330] [0.0] [cxt 0] Extracting to header stack 0, next header is 2
[14:43:21.168] [bmv2] [D] [thread 9330] [0.0] [cxt 0] Parser set: setting field (4, 7) from expression, new value is 2
[14:43:21.168] [bmv2] [D] [thread 9330] [0.0] [cxt 0] Parser state 'parse_stack': key is 00
[14:43:21.168] [bmv2] [T] [thread 9330] Bytes parsed: 54
[14:43:21.168] [bmv2] [D] [thread 9330] [0.0] [cxt 0] Parser 'parser': end
[14:43:21.168] [bmv2] [D] [thread 9330] [0.0] [cxt 0] Pipeline 'ingress': start
[14:43:21.168] [bmv2] [T] [thread 9330] [0.0] [cxt 0] Applying table 'table1'
[14:43:21.168] [bmv2] [D] [thread 9330] [0.0] [cxt 0] Looking up key:

[14:43:21.168] [bmv2] [D] [thread 9330] [0.0] [cxt 0] Table 'table1': miss
[14:43:21.168] [bmv2] [D] [thread 9330] [0.0] [cxt 0] Action entry is action1 -
[14:43:21.168] [bmv2] [D] [thread 9330] [0.0] [cxt 0] Pipeline 'ingress': end
[14:43:21.168] [bmv2] [D] [thread 9330] [0.0] [cxt 0] Cloning packet at ingress

All right, the clone is created.

[14:43:21.168] [bmv2] [D] [thread 9330] [0.1] [cxt 0] Parser 'parser': start
[14:43:21.168] [bmv2] [D] [thread 9330] [0.1] [cxt 0] Parser state 'start' has no switch, going to default next state
[14:43:21.168] [bmv2] [T] [thread 9330] Bytes parsed: 0
[14:43:21.168] [bmv2] [D] [thread 9330] [0.1] [cxt 0] Extracting header 'ethernet'
[14:43:21.169] [bmv2] [D] [thread 9330] [0.1] [cxt 0] Parser state 'parse_ethernet' has no switch, going to default next state
[14:43:21.169] [bmv2] [T] [thread 9330] Bytes parsed: 14
[14:43:21.169] [bmv2] [D] [thread 9330] [0.1] [cxt 0] Extracting to header stack 0, next header is 1
[14:43:21.169] [bmv2] [D] [thread 9330] [0.1] [cxt 0] Parser set: setting field (4, 7) from expression, new value is 3

My expected value is 1!

[14:43:21.169] [bmv2] [D] [thread 9330] [0.1] [cxt 0] Parser state 'parse_stack': key is 04
[14:43:21.169] [bmv2] [T] [thread 9330] Bytes parsed: 34
[14:43:21.169] [bmv2] [D] [thread 9330] [0.1] [cxt 0] Extracting to header stack 0, next header is 2
[14:43:21.169] [bmv2] [D] [thread 9330] [0.1] [cxt 0] Parser set: setting field (4, 7) from expression, new value is 4

My expected value is 2!

[14:43:21.169] [bmv2] [D] [thread 9330] [0.1] [cxt 0] Parser state 'parse_stack': key is 00
[14:43:21.169] [bmv2] [T] [thread 9330] Bytes parsed: 54
[14:43:21.169] [bmv2] [D] [thread 9330] [0.1] [cxt 0] Parser 'parser': end

[...]

[14:43:21.169] [bmv2] [D] [thread 9330] [0.4] [cxt 0] Extracting header 'ethernet'
[14:43:21.169] [bmv2] [D] [thread 9330] [0.4] [cxt 0] Parser state 'parse_ethernet' has no switch, going to default next state
[14:43:21.169] [bmv2] [T] [thread 9330] Bytes parsed: 14
[14:43:21.169] [bmv2] [D] [thread 9330] [0.4] [cxt 0] Extracting to header stack 0, next header is 1
terminate called after throwing an instance of 'std::bad_alloc'
what(): std::bad_alloc

This error might occur because the stack index is out of bounds.

from behavioral-model.

antoninbas avatar antoninbas commented on July 20, 2024

Assuming you are using a metadata field as your index counter, the easiest explanation is that you are including this field (or its parent header) in the cloning field list, which is the second parameter of the clone primitive. When a packet is cloned, all the metadata fields are set to 0 in the copy, except for the fields included in the cloning field list, which are preserved. All you would have to do is remove the metadata field used as an index from the cloning field list.
If this does not explain your issue, you may have to share with me some P4 code so I can reproduce it.

from behavioral-model.

cw299 avatar cw299 commented on July 20, 2024

Thanks, this was exactly my problem. I removed the counter from the cloning field list, now it's working fine.

You can find attached the resulting p4 program. Here is how it works: An incoming packet contains a stack of IPv4 addresses. The p4 program processes the stack and generates a separate packet (by clone operations) for each IPv4 address.

stack_processing.zip

from behavioral-model.

antoninbas avatar antoninbas commented on July 20, 2024

Support for s[last] in expressions was added by #292. s[next] is IMO only needed in parser when extracting.

from behavioral-model.

Related Issues (20)

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.