-
Notifications
You must be signed in to change notification settings - Fork 35
implement general unpack method (moved from of_core.utils) #397
Conversation
@beraldoleal should we create a
|
@diraol @beraldoleal, I believe it could be in the main module:
|
@diraol @erickvermot for now is better on utils. like @diraol said. |
@diraol, @beraldoleal, done. |
import pyof.v0x01.common.header | ||
import pyof.v0x01.common.utils | ||
import pyof.v0x04.common.header | ||
import pyof.v0x04.common.utils |
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.
@erickvermot you are not using this imported modules anywhere, so you should not import them here.
Considering your code, I would do:
from pyof import v0x01
from pyof import v0x04
pyof_version_libs = {0x01: v0x01,
0x04: v0x04}
Note that I'm using the from
statement, instead of the import
statement.
This is because on some tests I've performed related to the python importing system, this import
statement appeared to be less error prone than using the from ... import
statement, so I would give preference to use the latter.
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.
Even better:
from pyof import v0x01, v0x04
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.
anywhere = line 25 for example. Those imports are needed since importing pyof does not import the child modules by default.
The from statement is better suited when one tries to import a Class, function or variable from a given module, or when one wants to place the imported module in the current namespace.
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 checked this out and, unfortunately, Diraol suggestion doesn't work because this is a special case like Erick said. Linters can't detect unused import statements like these, but I can't think of a better way to do it right now.
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.
-
"unused import statements like these", That's because they are not unused, as I said before.
-
This is not a special case. Unless we make the imports inside the init s, those imports are needed.
|
||
try: | ||
header = pyof_lib.common.header.Header() | ||
header.unpack(packet[:8]) |
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.
@erickvermot the header will always have length 8 [just to make sure that on OF 1.3.5 and newer they still keep this behavior]?
Or should we use pyof_lib.common.header.Header.get_size()
instead of 8
?
If my comment make any sense, then we should "apply" it below also.
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.
headers always have length 8
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 then!
pyof/utils.py
Outdated
message.unpack(binary_data) | ||
else: | ||
raise UnpackException( | ||
'packet size does not match packet length field') |
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.
Shouldn't we always call unpack
, Even if we have no binary_data
?
If the specific Message does have a "body" it may always wait for its body. If no body was passed, then the unpack will fail - and it should! Eventually, if the "body" is optional (or some attributes are), then the unpack should handle it naturally without raising an exception.
If the specific message does not have a body, then the binary-data
is expected to be "empty", therefore the unpack should not have any problem being called.
On the current code we are "ignoring" when the Message (class) does have a mandatory body and the message was sent through the network just with the header and without the body, which shouldn't be accepted while doing the unpack, right? Does it make sense?
Considering my comment, it seems that this block can be something like
message.unpack(binary_data)
And I would also do the check len(binary_data) == header.length - 8
within the "unpack" method.
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.
This unpack function unpacks all the data there is.
It does not perform message validation. Which is currently not implemented in pyof (there are many issues opened about it).
About what the block does:
- If there is no data to unpack, then there is no reason to make the call.
- If the length of the data is different of whats in the header.length field, then there is no reason to make the call either.
+ this PR is about bringing the method from of_core to pyof. We need this to have more reliable tests. There are still many improvements to this function, but I plan to make them in a different PR (regarding version agnostic messages for ex like the hello msg, as we have discussed before).
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.
@diraol, @erickvermot told me something before that you might not be aware (see my review comment to write it in the module docstring): the purpose of this PR is to provide the same unpack of of_core to python-openflow tests. Thus, my review is based on copying the unpack method. Maybe we should move discussions about changing the current of_code code to another issue, wherever it will be (we must remove this duplication).
Regarding Erick's 2 bullets, I see those issues in a different way, respectively:
- If there's no data to unpack, it's dangerous to assume that it will always mean nothing. It should be up to each message to decide it. Thus, I believe we'd better always call unpack.
- This should be done in the message validation. If it is not done yet, I see no reason on implementing it quick and dirty in the wrong place.
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.
About the first parag:
This is stated in the title and in the mentioned issues
About the bullets, you are mixing message validation with packet validation.
Unpack method deals with the packet, so packet validation is important so it doesn't mess thing around. Message validation should not be done here.
So:
- if the packet is valid and there is nothing more to unpack, there is no reason to make the call.
- If the packet is invalid, it should stop unpacking. This is not 'quick and dirty', you just need to understand it better
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 know why GH didn't marked the 'resquest changes' status..
import pyof.v0x01.common.header | ||
import pyof.v0x01.common.utils | ||
import pyof.v0x04.common.header | ||
import pyof.v0x04.common.utils |
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 checked this out and, unfortunately, Diraol suggestion doesn't work because this is a special case like Erick said. Linters can't detect unused import statements like these, but I can't think of a better way to do it right now.
pyof/utils.py
Outdated
message = pyof_lib.common.utils.new_message_from_header(header) | ||
binary_data = packet[8:] | ||
if binary_data: | ||
if len(binary_data) == header.length - 8: |
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.
Is there a reason for adding this check to the of_core code?
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.
packet (not message) validation.
In of_core this is also done, just not inside the unpack function.
@@ -0,0 +1,37 @@ | |||
"""General Unpack utils for python-openflow.""" |
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.
Please, add a comment stating that you are copying the code from of_core, specifying the filename from its repo root. Also write that this is because you want to have the exact same behavior for testing purpose.
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.
pyof/utils.py
Outdated
message.unpack(binary_data) | ||
else: | ||
raise UnpackException( | ||
'packet size does not match packet length field') |
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.
@diraol, @erickvermot told me something before that you might not be aware (see my review comment to write it in the module docstring): the purpose of this PR is to provide the same unpack of of_core to python-openflow tests. Thus, my review is based on copying the unpack method. Maybe we should move discussions about changing the current of_code code to another issue, wherever it will be (we must remove this duplication).
Regarding Erick's 2 bullets, I see those issues in a different way, respectively:
- If there's no data to unpack, it's dangerous to assume that it will always mean nothing. It should be up to each message to decide it. Thus, I believe we'd better always call unpack.
- This should be done in the message validation. If it is not done yet, I see no reason on implementing it quick and dirty in the wrong place.
@cemsbr, you duplicated a comment, but comments about the bullets are in the review answer: #397 (comment) |
should I include the following mod in this PR? |
@macartur can you please try to understand this issue and make sure that all comments / changes requests are ok ? Thanks a lot. |
Implemented in #444. |
relates to #381
also provides way to #396