@@ -22,6 +22,8 @@ import (
22
22
23
23
"github.com/digitalocean/go-openvswitch/ovsnl/internal/ovsh"
24
24
"github.com/mdlayher/genetlink"
25
+ "github.com/mdlayher/netlink"
26
+ "github.com/mdlayher/netlink/nlenc"
25
27
)
26
28
27
29
// Sizes of various structures, used in unsafe casts.
@@ -30,12 +32,15 @@ const (
30
32
31
33
sizeofDPStats = int (unsafe .Sizeof (ovsh.DPStats {}))
32
34
sizeofDPMegaflowStats = int (unsafe .Sizeof (ovsh.DPMegaflowStats {}))
35
+ sizeofVportStats = int (unsafe .Sizeof (ovsh.VportStats {}))
33
36
)
34
37
35
38
// A Client is a Linux Open vSwitch generic netlink client.
36
39
type Client struct {
37
40
// Datapath provides access to DatapathService methods.
38
41
Datapath * DatapathService
42
+ // Vport provides access to VportService methods.
43
+ Vport * VportService
39
44
40
45
c * genetlink.Conn
41
46
}
@@ -111,6 +116,12 @@ func (c *Client) initFamily(f genetlink.Family) error {
111
116
c : c ,
112
117
}
113
118
return nil
119
+ case ovsh .VportFamily :
120
+ c .Vport = & VportService {
121
+ c : c ,
122
+ f : f ,
123
+ }
124
+ return nil
114
125
default :
115
126
// Unknown OVS netlink family, nothing we can do.
116
127
return fmt .Errorf ("unknown OVS generic netlink family: %q" , f .Name )
@@ -133,3 +144,132 @@ func parseHeader(b []byte) (ovsh.Header, error) {
133
144
h := * (* ovsh .Header )(unsafe .Pointer (& b [:sizeofHeader ][0 ]))
134
145
return h , nil
135
146
}
147
+
148
+ // NlMsgBuilder to build genetlink message
149
+ type NlMsgBuilder struct {
150
+ msg * genetlink.Message
151
+ }
152
+
153
+ // NewNlMsgBuilder construct a netlink message builder with genetlink.Message
154
+ func NewNlMsgBuilder () * NlMsgBuilder {
155
+ return & NlMsgBuilder {msg : & genetlink.Message {}}
156
+ }
157
+
158
+ // PutGenlMsgHdr set msg header with genetlink.Header
159
+ func (nlmsg * NlMsgBuilder ) PutGenlMsgHdr (command , version uint8 ) {
160
+ nlmsg .msg .Header = genetlink.Header {
161
+ Command : command ,
162
+ Version : version ,
163
+ }
164
+ }
165
+
166
+ // PutOvsHeader set ovs header with ovsh.Header
167
+ func (nlmsg * NlMsgBuilder ) PutOvsHeader (dpID int32 ) {
168
+ nlmsg .msg .Data = headerBytes (ovsh.Header {Ifindex : dpID })
169
+ }
170
+
171
+ // PutStringAttr put attribute with string value
172
+ func (nlmsg * NlMsgBuilder ) PutStringAttr (typ uint16 , value string ) error {
173
+ attrs := []netlink.Attribute {
174
+ {
175
+ Type : typ ,
176
+ Data : nlenc .Bytes (value ),
177
+ },
178
+ }
179
+ attr , err := netlink .MarshalAttributes (attrs )
180
+ if err != nil {
181
+ return fmt .Errorf ("marshal string attributes failed:%s" , err )
182
+ }
183
+
184
+ nlmsg .msg .Data = append (nlmsg .msg .Data [:], attr ... )
185
+ return nil
186
+ }
187
+
188
+ // PutUint8Attr put attribute with uint8 value
189
+ func (nlmsg * NlMsgBuilder ) PutUint8Attr (typ uint16 , value uint8 ) error {
190
+ attrs := []netlink.Attribute {
191
+ {
192
+ Type : typ ,
193
+ Data : nlenc .Uint8Bytes (value ),
194
+ },
195
+ }
196
+ attr , err := netlink .MarshalAttributes (attrs )
197
+ if err != nil {
198
+ return fmt .Errorf ("marshal uint8 attributes failed:%s" , err )
199
+ }
200
+
201
+ nlmsg .msg .Data = append (nlmsg .msg .Data [:], attr ... )
202
+ return nil
203
+ }
204
+
205
+ // PutUint16Attr put attribute with uint16 value
206
+ func (nlmsg * NlMsgBuilder ) PutUint16Attr (typ uint16 , value uint16 ) error {
207
+ attrs := []netlink.Attribute {
208
+ {
209
+ Type : typ ,
210
+ Data : nlenc .Uint16Bytes (value ),
211
+ },
212
+ }
213
+ attr , err := netlink .MarshalAttributes (attrs )
214
+ if err != nil {
215
+ return fmt .Errorf ("marshal uint16 attributes failed:%s" , err )
216
+ }
217
+
218
+ nlmsg .msg .Data = append (nlmsg .msg .Data [:], attr ... )
219
+ return nil
220
+ }
221
+
222
+ // PutUint32Attr put attribute with uint32 value
223
+ func (nlmsg * NlMsgBuilder ) PutUint32Attr (typ uint16 , value uint32 ) error {
224
+ attrs := []netlink.Attribute {
225
+ {
226
+ Type : typ ,
227
+ Data : nlenc .Uint32Bytes (value ),
228
+ },
229
+ }
230
+ attr , err := netlink .MarshalAttributes (attrs )
231
+ if err != nil {
232
+ return fmt .Errorf ("marshal uint32 attributes failed:%s" , err )
233
+ }
234
+
235
+ nlmsg .msg .Data = append (nlmsg .msg .Data [:], attr ... )
236
+ return nil
237
+ }
238
+
239
+ // PutSliceAttr put attribute with slice byte value
240
+ func (nlmsg * NlMsgBuilder ) PutSliceAttr (typ uint16 , value []byte ) error {
241
+ attrs := []netlink.Attribute {
242
+ {
243
+ Type : typ ,
244
+ Data : value ,
245
+ },
246
+ }
247
+ attr , err := netlink .MarshalAttributes (attrs )
248
+ if err != nil {
249
+ return fmt .Errorf ("marshal slice byte attributes failed:%s" , err )
250
+ }
251
+
252
+ nlmsg .msg .Data = append (nlmsg .msg .Data [:], attr ... )
253
+ return nil
254
+ }
255
+
256
+ // PutEmptyAttr put attribute with empty value
257
+ func (nlmsg * NlMsgBuilder ) PutEmptyAttr (typ uint16 ) error {
258
+ attrs := []netlink.Attribute {
259
+ {
260
+ Type : typ ,
261
+ },
262
+ }
263
+ attr , err := netlink .MarshalAttributes (attrs )
264
+ if err != nil {
265
+ return fmt .Errorf ("marshal empty attributes failed:%s" , err )
266
+ }
267
+
268
+ nlmsg .msg .Data = append (nlmsg .msg .Data [:], attr ... )
269
+ return nil
270
+ }
271
+
272
+ // Message generic netlink message
273
+ func (nlmsg * NlMsgBuilder ) Message () genetlink.Message {
274
+ return * nlmsg .msg
275
+ }
0 commit comments