-
Notifications
You must be signed in to change notification settings - Fork 22
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
Added support for openflow 1.5. #13
Conversation
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.
Before I review this, I'd like to understand why there seems to be no code reuse at all between the OF 1.3 implementation and the OF 1.5 implementation? I would expect OF 1.5 to incrementally build on previous OF versions and there should be a way to have mostly common code, while letting the library users import either openflow13
or openflow15
.
Hi Antonin, we used to have a discussion about how to support OF1.5, and we come to some agreements: 1) Antrea will switch to OF 1.5 completely after it is ready, and not use OF1.3 any more; 2) it is easier and quicker to support OF 1.5 only than support both OF 1.3 and OF 1.5 in libOpenflow. So Ashish chose to add a pure support OF 1.5 but not modify common code to support both. |
Thanks for the context @wenyingd. I did discuss with @ashish-varma offline on Friday and he explained the same thing to me. I am fine with the approach. |
18deaf1
to
14e83a5
Compare
} | ||
n += int(f.Stats.Len()) | ||
|
||
return err |
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.
s/return err/return nil/
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 generally prefer to return err so that in case the 'err' gets set, we return it.
I understand that in this particular function, we check for 'err != nil' and return immediately, but keeping 'return err' would make sure we don't accidentally return nil for an actual error.
openflow15/group.go
Outdated
func (g *GroupMod) Len() (n uint16) { | ||
n = g.Header.Len() | ||
n += 16 | ||
// if g.Command == OFPGC_DELETE { |
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.
Need to remove these lines?
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.
Sure. Would remove.
} | ||
|
||
// Add a bucket to group mod | ||
func (g *GroupMod) AddBucket(bkt Bucket) { |
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.
Could you help provide functions to support InsertBucket/RemoveBucket in a group?
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.
Yes. Would add.
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.
Would add as another commit.
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 support for InsertBucket/RemoveBucket in a group added?
openflow15/match.go
Outdated
n += len(b) | ||
} | ||
|
||
/* See if we need to pad it to make it align to 64bit boundary |
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 want to keep these line here or remove it?
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.
Removed.
openflow15/multipart.go
Outdated
if err != nil { | ||
return err | ||
} | ||
if req == nil { |
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.
For the case that the request body is empty (e.g., MultipartType_ControllerStatus, MultipartType_MeterFeatures, MultipartType_TableDesc), req
should be nil, then this error is not expected, correct?
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.
That is right. I will fix this.
n += 2 | ||
binary.BigEndian.PutUint32(data[n:], e.ExperimenterID) | ||
n += 4 | ||
headerBytes, err = e.Data.MarshalBinary() |
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.
ditto
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.
Sure. Would do.
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.
reminder.
openflow15/group.go
Outdated
GroupId uint32 /* Group identifier. */ | ||
BucketArrayLen uint16 /* Length of action buckets data. */ | ||
Pad uint16 | ||
ComandBucketId uint32 /* Bucket Id used as part of |
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.
ComandBucketId uint32 /* Bucket Id used as part of | |
CommandBucketId uint32 /* Bucket Id used as part of |
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.
Done
openflow15/openflow15.go
Outdated
) | ||
|
||
func Parse(b []byte) (message util.Message, err error) { | ||
fmt.Println("Parse_Type=", b[1]) |
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.
Forgot to remove?
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.
Yeah. Had added during unit test. Would remove.
openflow15/openflow15.go
Outdated
AuxilaryId uint8 | ||
pad []uint8 // Size 2 | ||
Capabilities uint32 | ||
//Actions uint32 |
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 we need 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.
No. Would Remove.
openflow15/openflow15.go
Outdated
n += uint16(len(s.DPID)) | ||
n += 16 | ||
/* | ||
for _, p := range s.Ports { |
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.
ditto
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.
Would take care. Thanks.
openflow15_test.go
Outdated
f := openflow15.NewInPortField(5) | ||
flowMod.Match.AddField(*f) | ||
//f = openflow15.NewEthTypeField(0x800) | ||
//flowMod.Match.AddField(*f) |
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.
remove them?
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.
Done
d719e11
to
d753d62
Compare
Cookie uint64 | ||
Match Match | ||
pad []uint8 | ||
Data util.Message |
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.
Why do you change the typd of Data from Ethernet to util.Message?
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.
As per Openflow 1.5, 7.2.3.11
"Packet-in messages must include the Packet Type Match Field in the match, unless the packet type is Ethernet."
This means that the packet included in the Packet In message could be Ethernet or other types. Does this break any existing functionality?
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 a blocking issue. I asked it because Antrea thought the Data filed type is Ethernet with OF1.3, but it changes when switching to OF1.5. This caused a compilation issue. But if it is as designed, I could change Antrea code to be compatible with the new field type.
} | ||
|
||
// oxm_id - OXM TLV Header | ||
type OxmId struct { |
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 this expected to use in flow action to represent a different field? In OpenFlow13, I use MatchField for this purpose, please add some functions to help users to create the target OxmId with a name string (e.g., the existing function FindFieldHeaderByName ) if you want it for the same purpose. It is because we can't expect all dev know every field's class, field, length, experimenterID.
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 a helper function to get the OxmId from a string. 'FindOxmIdByName'.
openflow15/match.go
Outdated
|
||
// IP_DSCP field | ||
type IpDscpField struct { | ||
dscp uint8 |
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.
Hi @ashish-varma , would you change this field as public? I know it is not introduced in your patch, but we need to set a masked field for IpDscpField, but the existing struct doesn't support 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.
Done.
3a4010a
to
ed02932
Compare
b78a7aa
to
5dc6e23
Compare
openflow15/openflow15.go
Outdated
if p.Data != nil { | ||
n += p.Data.Len() | ||
} | ||
//if n < 72 { return 72 } |
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 this line needed?
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.
Would remove it.
copy(b[0:], p.pad) | ||
data = append(data, b...) | ||
|
||
b, err = p.Data.MarshalBinary() |
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.
Misse err check?
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.
Would add.
var err error | ||
n := 0 | ||
|
||
err = c.Header.UnmarshalBinary(data[n:]) |
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.
ditto, err check
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.
Would add.
AuxilaryId uint8 | ||
pad []uint8 // Size 2 | ||
Capabilities uint32 | ||
Reserved uint32 |
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.
So Ports and Actions are removed from SwitchFeatures? Then how shall we get these information?
openflow15/match.go
Outdated
|
||
// IP_PROTO field | ||
type IpProtoField struct { | ||
protocol uint8 |
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 introduced by you, but it should be better to use a public property for such a library, then it is convenient for callers to reset the values if necessary.
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.
Done.
openflow15/match.go
Outdated
|
||
// Common struct for all port fields | ||
type PortField struct { | ||
port uint16 |
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.
ditto
openflow15/match.go
Outdated
|
||
// PACKET_TYPE field | ||
type PacketTypeField struct { | ||
namespace uint16 |
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.
ditto
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.
Done.
) | ||
|
||
func NewTableFeatures(t uint8) *TableFeatures { | ||
n := new(TableFeatures) |
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.
use tf as the variable ( instead of n ) ?
}, nil | ||
} | ||
|
||
func FindOxmIdByName(fieldName string, hasMask bool) (*OxmId, error) { |
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.
First, I am confuse if we could use OxmId instead of MatchField directly? Second, it looks the code is almost the same for these to functions, I think you can call FindFieldHeaderByName
inside FindOxmIdByName
, and generate an OxmId pointer object with *MatchField properties.
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.
Changed the function to use FindFieldHeaderByName inside FindOxmIdByName.
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 finished yet.
n += 2 | ||
copy(a.pad, data[n:n+6]) | ||
n += 6 | ||
return err |
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.
return err | |
return nil |
a.GroupId = binary.BigEndian.Uint32(data[n:]) | ||
n += 4 | ||
|
||
return err |
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.
return err | |
return nil |
} | ||
n += int(a.Field.Len()) | ||
|
||
return err |
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.
return err | |
return nil |
} | ||
n += a.OxmIdDst.Len() | ||
|
||
return err |
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.
return err | |
return nil |
data = append(data, bytes...) | ||
|
||
for _, bkt := range g.Buckets { | ||
bytes, err = bkt.MarshalBinary() |
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.
Why not handling the err?
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.
Done.
} | ||
|
||
for _, p := range b.Properties { | ||
bytes, err = p.MarshalBinary() |
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.
ditto
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.
Done.
} | ||
|
||
// Add a bucket to group mod | ||
func (g *GroupMod) AddBucket(bkt Bucket) { |
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 support for InsertBucket/RemoveBucket in a group added?
* Add unit tests for ClickHouse monitor Signed-off-by: Yanjun Zhou <zhouya@vmware.com>
openflow15/match.go
Outdated
// PACKET_TYPE field | ||
type PacketTypeField struct { | ||
Namespace uint16 | ||
Ns_type uint16 |
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.
nit: do not use charactors like _
or -
in the name of a property/type/object/variable/constant.
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.
Fixed.
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
@hongliangl @tnqn Would you give a last round review on this PR? |
LGTM, no further 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.
Thanks @ashish-varma. LGTM overall, a few errors not handled and a message length issue.
openflow15/flowstats.go
Outdated
func (s *Stats) MarshalBinary() (data []byte, err error) { | ||
data = make([]byte, int(s.Len())) | ||
n := 2 | ||
s.Length = s.Len() - 8 // 'Pad', 'Reserved' & 'Length' not part of 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.
The above comment says Length
is length of ofp_stats
excluding padding and length of Fields
should be length - 4
, which means the length should include Reserved & Length
.
I also checked spec of Flow Stats Header, it should include Reserved & 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.
You are right. Fixed.
* Added package openflow15 which implements the Openflow 1.5 protocol Marshal and Unmarshal functions. * Added the unit test (openflow15_test.go) file to test the Marshal/ Unmarshal of every Openflow 1.5 message. * Modified the README.md file to include support of Openflow 1.5. * Updated the VERSION file. Signed-off-by: Ashish Varma <ashishvarma.ovs@gmail.com>
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
Added package openflow15 which implements the Openflow 1.5 protocol
Marshal and Unmarshal functions.
Added the unit test (openflow15_test.go) file to test the Marshal/
Unmarshal of every Openflow 1.5 message.
Modified the README.md file to include support of Openflow 1.5.
Updated the VERSION file.
Signed-off-by: Ashish Varma ashishvarma.ovs@gmail.com