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

Added support for openflow 1.5. #13

Merged
merged 1 commit into from
Jul 8, 2022
Merged

Conversation

ashish-varma
Copy link

  • 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

Copy link

@antoninbas antoninbas left a 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.

@wenyingd wenyingd requested a review from tnqn September 27, 2021 01:28
@wenyingd
Copy link

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.

@antoninbas
Copy link

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.

}
n += int(f.Stats.Len())

return err
Copy link

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/

Copy link
Author

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.

func (g *GroupMod) Len() (n uint16) {
n = g.Header.Len()
n += 16
// if g.Command == OFPGC_DELETE {
Copy link

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?

Copy link
Author

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) {
Copy link

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?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes. Would add.

Copy link
Author

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.

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?

n += len(b)
}

/* See if we need to pad it to make it align to 64bit boundary
Copy link

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?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Removed.

if err != nil {
return err
}
if req == nil {
Copy link

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?

Copy link
Author

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()
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ditto

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure. Would do.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

reminder.

GroupId uint32 /* Group identifier. */
BucketArrayLen uint16 /* Length of action buckets data. */
Pad uint16
ComandBucketId uint32 /* Bucket Id used as part of
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
ComandBucketId uint32 /* Bucket Id used as part of
CommandBucketId uint32 /* Bucket Id used as part of

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

)

func Parse(b []byte) (message util.Message, err error) {
fmt.Println("Parse_Type=", b[1])
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Forgot to remove?

Copy link
Author

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.

AuxilaryId uint8
pad []uint8 // Size 2
Capabilities uint32
//Actions uint32
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we need this?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No. Would Remove.

n += uint16(len(s.DPID))
n += 16
/*
for _, p := range s.Ports {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ditto

Copy link
Author

@ashish-varma ashish-varma Jan 5, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would take care. Thanks.

f := openflow15.NewInPortField(5)
flowMod.Match.AddField(*f)
//f = openflow15.NewEthTypeField(0x800)
//flowMod.Match.AddField(*f)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

remove them?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

Cookie uint64
Match Match
pad []uint8
Data util.Message

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?

Copy link
Author

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?

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 {
Copy link

@wenyingd wenyingd Apr 26, 2022

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.

Copy link
Author

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'.


// IP_DSCP field
type IpDscpField struct {
dscp uint8

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.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

@ashish-varma ashish-varma force-pushed the main branch 2 times, most recently from 3a4010a to ed02932 Compare May 12, 2022 00:14
@ashish-varma ashish-varma force-pushed the main branch 3 times, most recently from b78a7aa to 5dc6e23 Compare May 25, 2022 04:59
if p.Data != nil {
n += p.Data.Len()
}
//if n < 72 { return 72 }

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this line needed?

Copy link
Author

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()

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Misse err check?

Copy link
Author

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:])

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ditto, err check

Copy link
Author

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

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?


// IP_PROTO field
type IpProtoField struct {
protocol uint8

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.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.


// Common struct for all port fields
type PortField struct {
port uint16

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ditto


// PACKET_TYPE field
type PacketTypeField struct {
namespace uint16

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ditto

Copy link
Author

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)

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) {

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.

Copy link
Author

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.

Copy link

@hongliangl hongliangl left a 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

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
return err
return nil

a.GroupId = binary.BigEndian.Uint32(data[n:])
n += 4

return err

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
return err
return nil

}
n += int(a.Field.Len())

return err

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
return err
return nil

}
n += a.OxmIdDst.Len()

return err

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
return err
return nil

data = append(data, bytes...)

for _, bkt := range g.Buckets {
bytes, err = bkt.MarshalBinary()

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?

Copy link
Author

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()

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ditto

Copy link
Author

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) {

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?

ruicao93 pushed a commit to ruicao93/libOpenflow that referenced this pull request Jun 19, 2022
* Add unit tests for ClickHouse monitor

Signed-off-by: Yanjun Zhou <zhouya@vmware.com>
// PACKET_TYPE field
type PacketTypeField struct {
Namespace uint16
Ns_type uint16

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.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed.

wenyingd
wenyingd previously approved these changes Jun 27, 2022
Copy link

@wenyingd wenyingd left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@wenyingd
Copy link

@hongliangl @tnqn Would you give a last round review on this PR?

@hongliangl
Copy link

LGTM, no further comment.

Copy link
Member

@tnqn tnqn left a 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.

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
Copy link
Member

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.

Copy link
Author

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>
Copy link
Member

@tnqn tnqn left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@wenyingd wenyingd merged commit 02150d8 into antrea-io:main Jul 8, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants