Skip to content

Commit

Permalink
feature: retrieve ovs vport
Browse files Browse the repository at this point in the history
operation like: List GetByID GetByName

resolve digitalocean#110

Signed-off-by: kwanhur <[email protected]>
  • Loading branch information
kwanhur committed Feb 27, 2022
1 parent 2a0f99c commit d63ec78
Show file tree
Hide file tree
Showing 5 changed files with 929 additions and 0 deletions.
1 change: 1 addition & 0 deletions AUTHORS
Original file line number Diff line number Diff line change
Expand Up @@ -14,3 +14,4 @@ Kei Nohguchi <[email protected]>
Neal Shrader <[email protected]>
Sangeetha Srikanth <[email protected]>
Franck Rupin <[email protected]>
Kwanhur Huang <[email protected]>
10 changes: 10 additions & 0 deletions ovsnl/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,4 +28,14 @@ if err != nil {
for _, d := range dps {
log.Printf("datapath: %q, flows: %d", d.Name, d.Stats.Flows)
}

// List OVS vports.
vports, err := c.Vport.List()
if err != nil {
log.Fatalf("failed to list vports: %v", err)
}

for _, p := range vports {
log.Printf("vport: %d %s type: %s stats: %v", p.ID, p.Name(), p.TypeName(), p.Stats)
}
```
140 changes: 140 additions & 0 deletions ovsnl/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ import (

"github.com/digitalocean/go-openvswitch/ovsnl/internal/ovsh"
"github.com/mdlayher/genetlink"
"github.com/mdlayher/netlink"
"github.com/mdlayher/netlink/nlenc"
)

// Sizes of various structures, used in unsafe casts.
Expand All @@ -30,12 +32,15 @@ const (

sizeofDPStats = int(unsafe.Sizeof(ovsh.DPStats{}))
sizeofDPMegaflowStats = int(unsafe.Sizeof(ovsh.DPMegaflowStats{}))
sizeofVportStats = int(unsafe.Sizeof(ovsh.VportStats{}))
)

// A Client is a Linux Open vSwitch generic netlink client.
type Client struct {
// Datapath provides access to DatapathService methods.
Datapath *DatapathService
// Vport provides access to VportService methods.
Vport *VportService

c *genetlink.Conn
}
Expand Down Expand Up @@ -111,6 +116,12 @@ func (c *Client) initFamily(f genetlink.Family) error {
c: c,
}
return nil
case ovsh.VportFamily:
c.Vport = &VportService{
c: c,
f: f,
}
return nil
default:
// Unknown OVS netlink family, nothing we can do.
return fmt.Errorf("unknown OVS generic netlink family: %q", f.Name)
Expand All @@ -133,3 +144,132 @@ func parseHeader(b []byte) (ovsh.Header, error) {
h := *(*ovsh.Header)(unsafe.Pointer(&b[:sizeofHeader][0]))
return h, nil
}

// NlMsgBuilder to build genetlink message
type NlMsgBuilder struct {
msg *genetlink.Message
}

// NewNlMsgBuilder construct a netlink message builder with genetlink.Message
func NewNlMsgBuilder() *NlMsgBuilder {
return &NlMsgBuilder{msg: &genetlink.Message{}}
}

// PutGenlMsgHdr set msg header with genetlink.Header
func (nlmsg *NlMsgBuilder) PutGenlMsgHdr(command, version uint8) {
nlmsg.msg.Header = genetlink.Header{
Command: command,
Version: version,
}
}

// PutOvsHeader set ovs header with ovsh.Header
func (nlmsg *NlMsgBuilder) PutOvsHeader(dpID int32) {
nlmsg.msg.Data = headerBytes(ovsh.Header{Ifindex: dpID})
}

// PutStringAttr put attribute with string value
func (nlmsg *NlMsgBuilder) PutStringAttr(typ uint16, value string) error {
attrs := []netlink.Attribute{
{
Type: typ,
Data: nlenc.Bytes(value),
},
}
attr, err := netlink.MarshalAttributes(attrs)
if err != nil {
return fmt.Errorf("marshal string attributes failed:%s", err)
}

nlmsg.msg.Data = append(nlmsg.msg.Data[:], attr...)
return nil
}

// PutUint8Attr put attribute with uint8 value
func (nlmsg *NlMsgBuilder) PutUint8Attr(typ uint16, value uint8) error {
attrs := []netlink.Attribute{
{
Type: typ,
Data: nlenc.Uint8Bytes(value),
},
}
attr, err := netlink.MarshalAttributes(attrs)
if err != nil {
return fmt.Errorf("marshal uint8 attributes failed:%s", err)
}

nlmsg.msg.Data = append(nlmsg.msg.Data[:], attr...)
return nil
}

// PutUint16Attr put attribute with uint16 value
func (nlmsg *NlMsgBuilder) PutUint16Attr(typ uint16, value uint16) error {
attrs := []netlink.Attribute{
{
Type: typ,
Data: nlenc.Uint16Bytes(value),
},
}
attr, err := netlink.MarshalAttributes(attrs)
if err != nil {
return fmt.Errorf("marshal uint16 attributes failed:%s", err)
}

nlmsg.msg.Data = append(nlmsg.msg.Data[:], attr...)
return nil
}

// PutUint32Attr put attribute with uint32 value
func (nlmsg *NlMsgBuilder) PutUint32Attr(typ uint16, value uint32) error {
attrs := []netlink.Attribute{
{
Type: typ,
Data: nlenc.Uint32Bytes(value),
},
}
attr, err := netlink.MarshalAttributes(attrs)
if err != nil {
return fmt.Errorf("marshal uint32 attributes failed:%s", err)
}

nlmsg.msg.Data = append(nlmsg.msg.Data[:], attr...)
return nil
}

// PutSliceAttr put attribute with slice byte value
func (nlmsg *NlMsgBuilder) PutSliceAttr(typ uint16, value []byte) error {
attrs := []netlink.Attribute{
{
Type: typ,
Data: value,
},
}
attr, err := netlink.MarshalAttributes(attrs)
if err != nil {
return fmt.Errorf("marshal slice byte attributes failed:%s", err)
}

nlmsg.msg.Data = append(nlmsg.msg.Data[:], attr...)
return nil
}

// PutEmptyAttr put attribute with empty value
func (nlmsg *NlMsgBuilder) PutEmptyAttr(typ uint16) error {
attrs := []netlink.Attribute{
{
Type: typ,
},
}
attr, err := netlink.MarshalAttributes(attrs)
if err != nil {
return fmt.Errorf("marshal empty attributes failed:%s", err)
}

nlmsg.msg.Data = append(nlmsg.msg.Data[:], attr...)
return nil
}

// Message generic netlink message
func (nlmsg *NlMsgBuilder) Message() genetlink.Message {
return *nlmsg.msg
}
Loading

0 comments on commit d63ec78

Please sign in to comment.