Skip to content

Commit be839a1

Browse files
authored
Merge pull request #7 from digitalocean/mdl-ovsh-header
ovsnl: add ovsh.Header byte functions, correct Datapath.List data
2 parents 75a380c + dfc97eb commit be839a1

File tree

3 files changed

+36
-11
lines changed

3 files changed

+36
-11
lines changed

ovsnl/client.go

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -125,3 +125,20 @@ func (c *Client) initFamily(f genetlink.Family) error {
125125

126126
return fmt.Errorf("unrecognized OVS generic netlink family: %q", f.Name)
127127
}
128+
129+
// headerBytes converts an ovsh.Header into a byte slice.
130+
func headerBytes(h ovsh.Header) []byte {
131+
b := *(*[sizeofHeader]byte)(unsafe.Pointer(&h))
132+
return b[:]
133+
}
134+
135+
// parseHeader converts a byte slice into ovsh.Header.
136+
func parseHeader(b []byte) (ovsh.Header, error) {
137+
// Verify that the byte slice is long enough before doing unsafe casts.
138+
if l := len(b); l < sizeofHeader {
139+
return ovsh.Header{}, fmt.Errorf("not enough data for OVS message header: %d bytes", l)
140+
}
141+
142+
h := *(*ovsh.Header)(unsafe.Pointer(&b[:sizeofHeader][0]))
143+
return h, nil
144+
}

ovsnl/datapath.go

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -103,8 +103,10 @@ func (s *DatapathService) List() ([]Datapath, error) {
103103
Command: ovsh.DpCmdGet,
104104
Version: uint8(s.f.Version),
105105
},
106-
// Query all datapaths
107-
Data: nlenc.Uint32Bytes(0),
106+
// Query all datapaths.
107+
Data: headerBytes(ovsh.Header{
108+
Ifindex: 0,
109+
}),
108110
}
109111

110112
flags := netlink.HeaderFlagsRequest | netlink.HeaderFlagsDump
@@ -122,15 +124,15 @@ func parseDatapaths(msgs []genetlink.Message) ([]Datapath, error) {
122124
dps := make([]Datapath, 0, len(msgs))
123125

124126
for _, m := range msgs {
125-
if l := len(m.Data); l < sizeofHeader {
126-
return nil, fmt.Errorf("not enough data for OVS message header: %d bytes", l)
127+
// Fetch the header at the beginning of the message.
128+
h, err := parseHeader(m.Data)
129+
if err != nil {
130+
return nil, err
127131
}
128132

129-
var dp Datapath
130-
131-
// Fetch the header at the beginning of the message.
132-
h := *(*ovsh.Header)(unsafe.Pointer(&m.Data[:sizeofHeader][0]))
133-
dp.Index = int(h.Ifindex)
133+
dp := Datapath{
134+
Index: int(h.Ifindex),
135+
}
134136

135137
// Skip the header to parse attributes.
136138
attrs, err := netlink.UnmarshalAttributes(m.Data[sizeofHeader:])

ovsnl/datapath_linux_test.go

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -135,7 +135,13 @@ func TestClientDatapathListOK(t *testing.T) {
135135
if diff := cmp.Diff(ovsh.DpCmdGet, int(greq.Header.Command)); diff != "" {
136136
t.Fatalf("unexpected generic netlink command (-want +got):\n%s", diff)
137137
}
138-
if diff := cmp.Diff(0, int(nlenc.Uint32(greq.Data))); diff != "" {
138+
139+
h, err := parseHeader(greq.Data)
140+
if err != nil {
141+
t.Fatalf("failed to parse OvS generic netlink header: %v", err)
142+
}
143+
144+
if diff := cmp.Diff(0, int(h.Ifindex)); diff != "" {
139145
t.Fatalf("unexpected datapath ID (-want +got):\n%s", diff)
140146
}
141147

@@ -171,7 +177,7 @@ func mustMarshalDatapath(dp Datapath) []byte {
171177
Ifindex: int32(dp.Index),
172178
}
173179

174-
hb := *(*[sizeofHeader]byte)(unsafe.Pointer(&h))
180+
hb := headerBytes(h)
175181

176182
s := ovsh.DPStats{
177183
Hit: dp.Stats.Hit,

0 commit comments

Comments
 (0)