Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Emitting of arbitrary data is not implemented #629

Closed
vgurevich opened this issue May 14, 2017 · 17 comments
Closed

Emitting of arbitrary data is not implemented #629

vgurevich opened this issue May 14, 2017 · 17 comments
Labels
fixed This topic is considered to be fixed.

Comments

@vgurevich
Copy link

P4_16 spec and core.p4 define two methods for packet_out

extern packet_out {
    void emit<T>(in T hdr);
    void emit<T>(in bool condition, in T data);
}

The compiler doesn't recognize the second method (conditional emit of arbitrary data) and reports the following error:

l3_switch.p4(416): error: packet.emit: argument must be a header, stack or union, or a struct of such types
        packet.emit(hdr.ethernet.isValid(), 16w0x0001);
        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

Searching through the testcases didn't turn up any examples for this construct either.

@mihaibudiu
Copy link
Contributor

This may also be a spec bug, I don't know whether we want to support arbitrary data. We agreed that the first emit only supports headers and derivatives. I am not sure this can even be implemented without some kind of special support from bmv2.

@cc10512
Copy link
Contributor

cc10512 commented May 14, 2017

The spec clearly states that emitting arbitrary data is allowed. BMV2 currently only supports headers.

@jafingerhut
Copy link
Contributor

I recall at least one conversation at a recent language design meeting where the topic of whether emit() should work on bit vectors (directly, not inside of a header), and it was decided that should be decided post P4-16 spec release, and at least the initial P4-16 spec release would not allow that.

It seems reasonable to me if the same restrictions apply equally to both the 1-arg and 2-arg variants of emit. I can open a PR on the spec for this and see what happens.

@jafingerhut
Copy link
Contributor

But wait, isn't the issue here that @vgurevich is trying the 2-argument emit, and it is not working, even when he restricts himself to a type that the 1-argument emit supports?

@vgurevich
Copy link
Author

First of all, I'd like to know how do we plan to emit variable-length headers :) Something tells me we will need a two-argument emit for that.

Emitting arbitrary data, I think is also quite useful. If we decide to postpone it, it's fine, but then it will be a spec bug :) In general, I think that real deparsers (e.g. in PSA) will be much more complex than the spec currently suggests.

@jnfoster
Copy link
Contributor

jnfoster commented May 14, 2017 via email

@jnfoster
Copy link
Contributor

jnfoster commented May 14, 2017 via email

@jafingerhut
Copy link
Contributor

jafingerhut commented May 14, 2017

@vgurevich The 2-argument emit is not needed for a header containing varbit fields. The spec allows headers containing varbit<W> fields to be emit'ed via either the 1- or 2-argument emit. Whether the current implementation does it correctly I don't happen to know, but it ought to.

The 2-argument emit seems to me completely superfluous, if it is limited to the same types that the 1-argument emit supports, because it can trivially be implemented via the 1-argument emit with an 'if' wrapped around it in the deparser control block. I am perfectly happy if the 2-argument emit is limited to the same types supported by the 1-argument emit in the P4-16 1.0 spec.

Targets are allowed to extend either or both of the emit variants to work on other types if they want to.

@vgurevich
Copy link
Author

@jnfoster : I do agree that the conditional part of 2-argument emit is superfluous. I think it came about because the 1-argument emit is expressed via 2-argument one. I mean, one could also argue that the check for the header validity in 1-argument emit is superfluous, but the fact is that with this check the code is much more compact and easier to read.

More importantly, however, is the fact that the 1-argument emit is explicitly defined for headers and the types derived from headers (header_unions and structs) only, precisely because it does this validity check. It can be stretched to handle data ("if a type doesn't have isValid() method it is assumed to return true"), but that might be a little too much.

@vgurevich
Copy link
Author

@jafingerhut I think you are right. Section 8.8 specifically suggests that this should be possible. I think we should try it.

@cc10512
Copy link
Contributor

cc10512 commented May 15, 2017

I thought there was a desire not to introduce control flow in the deparser and thus, emit requires the valid bit in headers. @jnfoster makes the argument that he prefers the explicit if statement. I do too, but this is a matter of taste.
I guess you can put arbitrary data using emit, and assume that the valid bit is always true, but then you don't need the condition at all. The question with allowing non-header data in the deparser is what do you do with the packet at the other end? Someone will have to parse the packet header, and then someone will have to declare a header type for it. Can you give an example of where this would work without declaring a header?

@jafingerhut
Copy link
Contributor

@cc10512 I will let @jnfoster speak for himself, but I would guess he is not proposing eliminating the header validity check in the 1-argument emit. He is saying that 2-argument emit can be written with 1-argument emit wrapped inside of an 'if' statement.

The only possible reason I can imagine wanting to avoid explicit 'if' statements in a deparser are target-specific restrictions on deparser complexity. I would think that it should be just as easy for a compiler for a target to detect too much complexity in a deparser control block, as it can in other control blocks (even if that maximum implemented complexity is lower in a deparser than in other control blocks).

@mihaibudiu
Copy link
Contributor

In the spirit of simplicity I vote for removing the 2-argument emit altogether from the spec.

@vgurevich
Copy link
Author

@mbudiu-vmw I guess that's OK. If someone wants to output some custom stuff, it won't hurt to require them to define a header.

We will probably have to revisit this a little later anyway, but for now we are good as long as the other issues (emitting a struct, etc.) are resolved.

@jnfoster
Copy link
Contributor

jnfoster commented May 15, 2017

I think the proposal is: packet_out has one method declared with the following type;

void emit<T>(in T data);

that can be used with any type whatsoever.

In the short term, a custom header might be needed until p4c catches up. But long-term, I don't think it would be necessary.

Did I get that right?

@jafingerhut
Copy link
Contributor

jafingerhut commented May 15, 2017

@jnfoster and this 1-argument emit is still like the currently defined one, in that it uses the valid bit of a header, header_union, or the multiple header valid bits in a header stack to control whether anything is emitted? If so, sounds good to me. Keeping that header validity check inside of emit's implementation does seem very convenient and useful.

@jnfoster
Copy link
Contributor

Yep. In this design, emit would be a "magical" polymorphic function that needs to use type introspection to do its job (as does extract, by the way).

I agree that emit should do the right thing wrt validity bits.

mihaibudiu pushed a commit to mihaibudiu/p4c-clone that referenced this issue May 15, 2017
@mihaibudiu mihaibudiu added the fixed This topic is considered to be fixed. label May 15, 2017
mihaibudiu pushed a commit to mihaibudiu/p4c-clone that referenced this issue May 15, 2017
mihaibudiu pushed a commit to mihaibudiu/p4c-clone that referenced this issue May 23, 2017
mihaibudiu pushed a commit that referenced this issue May 24, 2017
mihaibudiu pushed a commit that referenced this issue May 30, 2017
* Fix for issue #638

* IRGen fixes

- support for autogenerating methods in nested classes
- support for friend functions
- misc bug fixes

* cpplint fixes

* Update comment

* Minor change in bmv2 backend: set action_const (#652)

In the bmv2 JSON, a match-table can indicate that its default action is
constant (using 'action_const') and that the default action entry
(action + action parameter values) is constant (using
'action_entry_const'). `action_entry_const == true => action_const ==
true`. The bmv2 backend was setting 'action_entry_const' correctly, but
'action_const' was always set to false. Note that P4_16 does not make a
difference between the 2, the presence of `const` in the P4_16 source
implies that both attributes should be true.

* Fix for issue #629 (#636)

* Support emits of structs; test parsing of varbit fields (#634)

* Support emits of structs; test parsing of varbit fields

* Fixes issue #447 and #630

* Updated reference outputs

* Additional tests and bug-fixes for varbits

* Fix for issue #638
* Allow empty actions list in tables
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
fixed This topic is considered to be fixed.
Projects
None yet
Development

No branches or pull requests

5 participants