-
Notifications
You must be signed in to change notification settings - Fork 23
Add support for large packet in the packetIn2 message #80
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
Conversation
b13c44e to
41e5b58
Compare
|
A few questions, if I may.
|
@vanytsvetkov Thanks for providing the feedback. It is the issue this change is expected to resolve: antrea-io/antrea#7386 The new value of the property is set/consumed only inside libOpenflow rather than updating OVS source code. The new flag is used only when a large packetIn message is received in which the actual size of message is overflow, so the length directly decoded from the bytes is untrusted. If we search solution from outside repository, it means we need to ask OVS to extend the OpenFlow message format, e.g., switch the type of "length" field from uint16 to uint32, it may introduce more change in most of the OpenFlow users. So I don't think it is acceptable in a short time. |
Thank you for your reply, now everything is clear. |
openflow13/bundles.go
Outdated
| n += 4 | ||
| p.ExperimenterType = binary.BigEndian.Uint32(data[n:]) | ||
| n += 4 | ||
| if len(data) < int(p.Length) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am having a hard time understanding this code. I took a look at the Openflow spec and we should always have len(data) >= int(p.Length), i.e., the length of the message should be at least equal to the property length (which includes header + experimenter data). What am I missing?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good catch, it should be an issue existing for long. I think here should be if n < int(p.Length)
a1f3333 to
3bcc3ff
Compare
319558c to
58ad864
Compare
|
@antoninbas I removed "AntreaLargePacket" by modifying the message "unmarshal" logic in the latest update, could you take another look? |
ddba8b4 to
e3d225b
Compare
openflow15/nxt_message.go
Outdated
| return uint16(p.ActLength()) | ||
| } | ||
|
|
||
| func (p *PacketIn2PropPacket) ActLength() int { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looking at the code I am having a hard time understanding why we need the ActLength method instead of just putting the correct implementation in the Len method for PacketIn2PropPacket? Then we would not need getPacketIn2PropertyLength?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The type of return value for function Len is uint16, it always map to the value of field "Length". And the function Len is defined in the interface Message. If we update the value type from uint16 to int, the impact is huge, we need to update almost all messages.
e3d225b to
b856438
Compare
b856438 to
aa26a34
Compare
|
@antoninbas Do you have other comments on this PR? Or can we move forward? |
antoninbas
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
While I am fine with the change, as I mentioned to you offline it feels like this is a bug in OVS (they should never generate an invalid Openflow message like this), and we should try to get to the bottom of this
openflow15/nxt_message.go
Outdated
| } | ||
|
|
||
| return nil | ||
| func getPacketIn2PropertyLength(prop Property) int { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The getPacketIn2PropertyLength function returns the length of any property, not just PacketIn2PropPacket, so I am not sure why the function is named like this.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Renamed as getPropertyLength.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It doesn't seem that this comment has been addressed?
Can you make sure other resolved comments have been addressed as well?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
updated.
aa26a34 to
82aa839
Compare
|
OVS issue is created: openvswitch/ovs-issues#371 |
|
@antoninbas Do you have other comments on this change? |
openflow15/nxt_message.go
Outdated
| } | ||
|
|
||
| return nil | ||
| func getPacketIn2PropertyLength(prop Property) int { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It doesn't seem that this comment has been addressed?
Can you make sure other resolved comments have been addressed as well?
util/stream.go
Outdated
| } | ||
| // Check if the message is Type_PacketIn2 or not. | ||
| experimenterType := binary.BigEndian.Uint32(venderHeaderMessageBytes[12:]) | ||
| if experimenterType != 30 { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok, and anyway this code is not supposed to be specific to openflow15
But maybe we should just redefine local constants in this file?
| } | ||
|
|
||
| // Handle inbound messages | ||
| func (m *MessageStream) inbound() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
do you have good confidence that the updated function will perform as well, or almost as well (performance-wise), as the previous version?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not did some performance test yet. In theory, the new logic should perform better.
82aa839 to
3c8cd16
Compare
3c8cd16 to
c5f6902
Compare
antoninbas
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM, I think @tnqn should take a look too if he has time
util/stream.go
Outdated
| } | ||
| // Check if the message is Type_PacketIn2 or not. | ||
| experimenterType := binary.BigEndian.Uint32(venderHeaderMessageBytes[12:]) | ||
| if experimenterType != 30 { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I was just suggesting adding local constants const experimenterTypePacketIn2 = 30 and const messageTypeVendorHeader = 4 in this file, not any major refactoring
c5f6902 to
f50ea96
Compare
| return uint16(p.actualLength()) | ||
| } | ||
|
|
||
| func (p *PacketIn2PropPacket) actualLength() int { | ||
| n := int(p.PropHeader.Len()) + int(p.Packet.Len()) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If Len() just calls actualLength(), why it needs two functions?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Function Len return type is uint16, which is defined in the interface, if the sum of the fields is exceeds 2^16, the result will overflow. Function actualLength return type is int,
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Added comments in the code.
1. Refine the inbound function in openflow stream. 2. Fix byte slice copy issues. 3. Fix the potential overflow issue when encoding packetOut message Signed-off-by: Wenying Dong <wenying.dong@broadcom.com>
f50ea96 to
2efa1bc
Compare
| length, err := getMessageLength(reader) | ||
| var smallOFErr *smallMessageError | ||
| var netErr *net.OpError | ||
| if errors.Is(err, io.EOF) || |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Doesn't Peek return ErrBufferFull when n is larger than buffer size? Why doesn't it handle that but EOF and other errors?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't get your question, "n" is always controlled by our call on Peek, the max value used in our function "getMessageLength" is 20, while reader may set its buf size with 4096 at least, so we shall not hit the issue.
While other errors we explicitly set are to catch the exceptions that we may hit in the runtime like connection issues and the message encoding issues from the sender (e.g. OVS).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
got it, thanks for explaining.
Fixes #7386 See antrea-io/libOpenflow#80 Signed-off-by: Wenying Dong <wenying.dong@broadcom.com>
Uh oh!
There was an error while loading. Please reload this page.