aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatt Layher <mdlayher@gmail.com>2018-08-14 15:15:07 -0400
committerBen Kochie <superq@gmail.com>2018-08-14 21:15:07 +0200
commitd84873727f7679b2d782ecd27f3cc8ecd365457f (patch)
treed6704b3d92e130d10ced23df90350a6aaac59396
parent60c827231afe2a7621ee632e02c3dd94e0faa19f (diff)
downloadprometheus_node_collector-d84873727f7679b2d782ecd27f3cc8ecd365457f.tar.bz2
prometheus_node_collector-d84873727f7679b2d782ecd27f3cc8ecd365457f.tar.xz
prometheus_node_collector-d84873727f7679b2d782ecd27f3cc8ecd365457f.zip
vendor: bump github.com/mdlayher/wifi and dependencies (#1045)
Signed-off-by: Matt Layher <mdlayher@gmail.com>
-rw-r--r--vendor/github.com/mdlayher/genetlink/conn.go10
-rw-r--r--vendor/github.com/mdlayher/genetlink/family_linux.go94
-rw-r--r--vendor/github.com/mdlayher/netlink/attribute.go222
-rw-r--r--vendor/github.com/mdlayher/netlink/conn.go192
-rw-r--r--vendor/github.com/mdlayher/netlink/conn_linux.go90
-rw-r--r--vendor/github.com/mdlayher/netlink/conn_others.go53
-rw-r--r--vendor/github.com/mdlayher/netlink/debug.go71
-rw-r--r--vendor/github.com/mdlayher/netlink/doc.go20
-rw-r--r--vendor/github.com/mdlayher/netlink/nlenc/endian.go16
-rw-r--r--vendor/vendor.json22
10 files changed, 608 insertions, 182 deletions
diff --git a/vendor/github.com/mdlayher/genetlink/conn.go b/vendor/github.com/mdlayher/genetlink/conn.go
index 2752982..019d43f 100644
--- a/vendor/github.com/mdlayher/genetlink/conn.go
+++ b/vendor/github.com/mdlayher/genetlink/conn.go
@@ -67,6 +67,16 @@ func (c *Conn) SetBPF(filter []bpf.RawInstruction) error {
67 return c.c.SetBPF(filter) 67 return c.c.SetBPF(filter)
68} 68}
69 69
70// RemoveBPF removes a BPF filter from a Conn.
71func (c *Conn) RemoveBPF() error {
72 return c.c.RemoveBPF()
73}
74
75// SetOption enables or disables a netlink socket option for the Conn.
76func (c *Conn) SetOption(option netlink.ConnOption, enable bool) error {
77 return c.c.SetOption(option, enable)
78}
79
70// Send sends a single Message to netlink, wrapping it in a netlink.Message 80// Send sends a single Message to netlink, wrapping it in a netlink.Message
71// using the specified generic netlink family and flags. On success, Send 81// using the specified generic netlink family and flags. On success, Send
72// returns a copy of the netlink.Message with all parameters populated, for 82// returns a copy of the netlink.Message with all parameters populated, for
diff --git a/vendor/github.com/mdlayher/genetlink/family_linux.go b/vendor/github.com/mdlayher/genetlink/family_linux.go
index 66fd4b1..9b8f0d6 100644
--- a/vendor/github.com/mdlayher/genetlink/family_linux.go
+++ b/vendor/github.com/mdlayher/genetlink/family_linux.go
@@ -16,10 +16,6 @@ var (
16 // errInvalidFamilyVersion is returned when a family's version is greater 16 // errInvalidFamilyVersion is returned when a family's version is greater
17 // than an 8-bit integer. 17 // than an 8-bit integer.
18 errInvalidFamilyVersion = errors.New("invalid family version attribute") 18 errInvalidFamilyVersion = errors.New("invalid family version attribute")
19
20 // errInvalidMulticastGroupArray is returned when a multicast group array
21 // of attributes is malformed.
22 errInvalidMulticastGroupArray = errors.New("invalid multicast group attribute array")
23) 19)
24 20
25// getFamily retrieves a generic netlink family with the specified name. 21// getFamily retrieves a generic netlink family with the specified name.
@@ -85,13 +81,8 @@ func (c *Conn) listFamilies() ([]Family, error) {
85func buildFamilies(msgs []Message) ([]Family, error) { 81func buildFamilies(msgs []Message) ([]Family, error) {
86 families := make([]Family, 0, len(msgs)) 82 families := make([]Family, 0, len(msgs))
87 for _, m := range msgs { 83 for _, m := range msgs {
88 attrs, err := netlink.UnmarshalAttributes(m.Data)
89 if err != nil {
90 return nil, err
91 }
92
93 var f Family 84 var f Family
94 if err := (&f).parseAttributes(attrs); err != nil { 85 if err := (&f).parseAttributes(m.Data); err != nil {
95 return nil, err 86 return nil, err
96 } 87 }
97 88
@@ -101,66 +92,79 @@ func buildFamilies(msgs []Message) ([]Family, error) {
101 return families, nil 92 return families, nil
102} 93}
103 94
104// parseAttributes parses netlink attributes into a Family's fields. 95// parseAttributes decodes netlink attributes into a Family's fields.
105func (f *Family) parseAttributes(attrs []netlink.Attribute) error { 96func (f *Family) parseAttributes(b []byte) error {
106 for _, a := range attrs { 97 ad, err := netlink.NewAttributeDecoder(b)
107 switch a.Type { 98 if err != nil {
99 return err
100 }
101
102 for ad.Next() {
103 switch ad.Type() {
108 case unix.CTRL_ATTR_FAMILY_ID: 104 case unix.CTRL_ATTR_FAMILY_ID:
109 f.ID = nlenc.Uint16(a.Data) 105 f.ID = ad.Uint16()
110 case unix.CTRL_ATTR_FAMILY_NAME: 106 case unix.CTRL_ATTR_FAMILY_NAME:
111 f.Name = nlenc.String(a.Data) 107 f.Name = ad.String()
112 case unix.CTRL_ATTR_VERSION: 108 case unix.CTRL_ATTR_VERSION:
113 v := nlenc.Uint32(a.Data) 109 v := ad.Uint32()
114 if v > math.MaxUint8 { 110 if v > math.MaxUint8 {
115 return errInvalidFamilyVersion 111 return errInvalidFamilyVersion
116 } 112 }
117 113
118 f.Version = uint8(v) 114 f.Version = uint8(v)
119 case unix.CTRL_ATTR_MCAST_GROUPS: 115 case unix.CTRL_ATTR_MCAST_GROUPS:
120 groups, err := parseMulticastGroups(a.Data) 116 ad.Do(func(b []byte) error {
121 if err != nil { 117 groups, err := parseMulticastGroups(b)
122 return err 118 if err != nil {
123 } 119 return err
124 120 }
125 f.Groups = groups 121
122 f.Groups = groups
123 return nil
124 })
126 } 125 }
127 } 126 }
128 127
129 return nil 128 return ad.Err()
130} 129}
131 130
132// parseMulticastGroups parses an array of multicast group nested attributes 131// parseMulticastGroups parses an array of multicast group nested attributes
133// into a slice of MulticastGroups. 132// into a slice of MulticastGroups.
134func parseMulticastGroups(b []byte) ([]MulticastGroup, error) { 133func parseMulticastGroups(b []byte) ([]MulticastGroup, error) {
135 attrs, err := netlink.UnmarshalAttributes(b) 134 ad, err := netlink.NewAttributeDecoder(b)
136 if err != nil { 135 if err != nil {
137 return nil, err 136 return nil, err
138 } 137 }
139 138
140 groups := make([]MulticastGroup, 0, len(attrs)) 139 var groups []MulticastGroup
141 for i, a := range attrs { 140 for ad.Next() {
142 // The type attribute is essentially an array index here; it starts 141 ad.Do(func(b []byte) error {
143 // at 1 and should increment for each new array element 142 adi, err := netlink.NewAttributeDecoder(b)
144 if int(a.Type) != i+1 { 143 if err != nil {
145 return nil, errInvalidMulticastGroupArray 144 return err
146 } 145 }
147 146
148 nattrs, err := netlink.UnmarshalAttributes(a.Data) 147 var g MulticastGroup
149 if err != nil { 148 for adi.Next() {
150 return nil, err 149 switch adi.Type() {
151 } 150 case unix.CTRL_ATTR_MCAST_GRP_NAME:
151 g.Name = adi.String()
152 case unix.CTRL_ATTR_MCAST_GRP_ID:
153 g.ID = adi.Uint32()
154 }
155 }
152 156
153 var g MulticastGroup 157 if err := ad.Err(); err != nil {
154 for _, na := range nattrs { 158 return err
155 switch na.Type {
156 case unix.CTRL_ATTR_MCAST_GRP_NAME:
157 g.Name = nlenc.String(na.Data)
158 case unix.CTRL_ATTR_MCAST_GRP_ID:
159 g.ID = nlenc.Uint32(na.Data)
160 } 159 }
161 }
162 160
163 groups = append(groups, g) 161 groups = append(groups, g)
162 return nil
163 })
164 }
165
166 if err := ad.Err(); err != nil {
167 return nil, err
164 } 168 }
165 169
166 return groups, nil 170 return groups, nil
diff --git a/vendor/github.com/mdlayher/netlink/attribute.go b/vendor/github.com/mdlayher/netlink/attribute.go
index d06af47..2443c6e 100644
--- a/vendor/github.com/mdlayher/netlink/attribute.go
+++ b/vendor/github.com/mdlayher/netlink/attribute.go
@@ -1,7 +1,9 @@
1package netlink 1package netlink
2 2
3import ( 3import (
4 "encoding/binary"
4 "errors" 5 "errors"
6 "fmt"
5 7
6 "github.com/mdlayher/netlink/nlenc" 8 "github.com/mdlayher/netlink/nlenc"
7) 9)
@@ -9,9 +11,6 @@ import (
9var ( 11var (
10 // errInvalidAttribute specifies if an Attribute's length is incorrect. 12 // errInvalidAttribute specifies if an Attribute's length is incorrect.
11 errInvalidAttribute = errors.New("invalid attribute; length too short or too large") 13 errInvalidAttribute = errors.New("invalid attribute; length too short or too large")
12 // errInvalidAttributeFlags specifies if an Attribute's flag configuration is invalid.
13 // From a comment in Linux/include/uapi/linux/netlink.h, Nested and NetByteOrder are mutually exclusive.
14 errInvalidAttributeFlags = errors.New("invalid attribute; type cannot have both nested and net byte order flags")
15) 14)
16 15
17// An Attribute is a netlink attribute. Attributes are packed and unpacked 16// An Attribute is a netlink attribute. Attributes are packed and unpacked
@@ -25,48 +24,18 @@ type Attribute struct {
25 24
26 // An arbitrary payload which is specified by Type. 25 // An arbitrary payload which is specified by Type.
27 Data []byte 26 Data []byte
28
29 // Whether the attribute's data contains nested attributes. Note that not
30 // all netlink families set this value. The programmer should consult
31 // documentation and inspect an attribute's data to determine if nested
32 // attributes are present.
33 Nested bool
34
35 // Whether the attribute's data is in network (true) or native (false) byte order.
36 NetByteOrder bool
37} 27}
38 28
39// #define NLA_F_NESTED
40const nlaNested uint16 = 0x8000
41
42// #define NLA_F_NET_BYTE_ORDER
43const nlaNetByteOrder uint16 = 0x4000
44
45// Masks all bits except for Nested and NetByteOrder.
46const nlaTypeMask = ^(nlaNested | nlaNetByteOrder)
47
48// MarshalBinary marshals an Attribute into a byte slice. 29// MarshalBinary marshals an Attribute into a byte slice.
49func (a Attribute) MarshalBinary() ([]byte, error) { 30func (a Attribute) MarshalBinary() ([]byte, error) {
50 if int(a.Length) < nlaHeaderLen { 31 if int(a.Length) < nlaHeaderLen {
51 return nil, errInvalidAttribute 32 return nil, errInvalidAttribute
52 } 33 }
53 34
54 if a.NetByteOrder && a.Nested {
55 return nil, errInvalidAttributeFlags
56 }
57
58 b := make([]byte, nlaAlign(int(a.Length))) 35 b := make([]byte, nlaAlign(int(a.Length)))
59 36
60 nlenc.PutUint16(b[0:2], a.Length) 37 nlenc.PutUint16(b[0:2], a.Length)
61 38 nlenc.PutUint16(b[2:4], a.Type)
62 switch {
63 case a.Nested:
64 nlenc.PutUint16(b[2:4], a.Type|nlaNested)
65 case a.NetByteOrder:
66 nlenc.PutUint16(b[2:4], a.Type|nlaNetByteOrder)
67 default:
68 nlenc.PutUint16(b[2:4], a.Type)
69 }
70 39
71 copy(b[nlaHeaderLen:], a.Data) 40 copy(b[nlaHeaderLen:], a.Data)
72 41
@@ -80,22 +49,12 @@ func (a *Attribute) UnmarshalBinary(b []byte) error {
80 } 49 }
81 50
82 a.Length = nlenc.Uint16(b[0:2]) 51 a.Length = nlenc.Uint16(b[0:2])
83 52 a.Type = nlenc.Uint16(b[2:4])
84 // Only hold the rightmost 14 bits in Type
85 a.Type = nlenc.Uint16(b[2:4]) & nlaTypeMask
86
87 // Boolean flags extracted from the two leftmost bits of Type
88 a.Nested = (nlenc.Uint16(b[2:4]) & nlaNested) > 0
89 a.NetByteOrder = (nlenc.Uint16(b[2:4]) & nlaNetByteOrder) > 0
90 53
91 if nlaAlign(int(a.Length)) > len(b) { 54 if nlaAlign(int(a.Length)) > len(b) {
92 return errInvalidAttribute 55 return errInvalidAttribute
93 } 56 }
94 57
95 if a.NetByteOrder && a.Nested {
96 return errInvalidAttributeFlags
97 }
98
99 switch { 58 switch {
100 // No length, no data 59 // No length, no data
101 case a.Length == 0: 60 case a.Length == 0:
@@ -139,6 +98,9 @@ func MarshalAttributes(attrs []Attribute) ([]byte, error) {
139} 98}
140 99
141// UnmarshalAttributes unpacks a slice of Attributes from a single byte slice. 100// UnmarshalAttributes unpacks a slice of Attributes from a single byte slice.
101//
102// It is recommend to use the AttributeDecoder type where possible instead of calling
103// UnmarshalAttributes and using package nlenc functions directly.
142func UnmarshalAttributes(b []byte) ([]Attribute, error) { 104func UnmarshalAttributes(b []byte) ([]Attribute, error) {
143 var attrs []Attribute 105 var attrs []Attribute
144 var i int 106 var i int
@@ -164,3 +126,173 @@ func UnmarshalAttributes(b []byte) ([]Attribute, error) {
164 126
165 return attrs, nil 127 return attrs, nil
166} 128}
129
130// An AttributeDecoder provides a safe, iterator-like, API around attribute
131// decoding.
132//
133// It is recommend to use an AttributeDecoder where possible instead of calling
134// UnmarshalAttributes and using package nlenc functions directly.
135//
136// The Err method must be called after the Next method returns false to determine
137// if any errors occurred during iteration.
138type AttributeDecoder struct {
139 // ByteOrder defines a specific byte order to use when processing integer
140 // attributes. ByteOrder should be set immediately after creating the
141 // AttributeDecoder: before any attributes are parsed.
142 //
143 // If not set, the native byte order will be used.
144 ByteOrder binary.ByteOrder
145
146 // The attributes being worked on, and the iterator index into the slice of
147 // attributes.
148 attrs []Attribute
149 i int
150
151 // Any error encountered while decoding attributes.
152 err error
153}
154
155// NewAttributeDecoder creates an AttributeDecoder that unpacks Attributes
156// from b and prepares the decoder for iteration.
157func NewAttributeDecoder(b []byte) (*AttributeDecoder, error) {
158 attrs, err := UnmarshalAttributes(b)
159 if err != nil {
160 return nil, err
161 }
162
163 return &AttributeDecoder{
164 // By default, use native byte order.
165 ByteOrder: nlenc.NativeEndian(),
166
167 attrs: attrs,
168 }, nil
169}
170
171// Next advances the decoder to the next netlink attribute. It returns false
172// when no more attributes are present, or an error was encountered.
173func (ad *AttributeDecoder) Next() bool {
174 if ad.err != nil {
175 // Hit an error, stop iteration.
176 return false
177 }
178
179 ad.i++
180
181 if len(ad.attrs) < ad.i {
182 // No more attributes, stop iteration.
183 return false
184 }
185
186 return true
187}
188
189// Type returns the Attribute.Type field of the current netlink attribute
190// pointed to by the decoder.
191func (ad *AttributeDecoder) Type() uint16 {
192 return ad.attr().Type
193}
194
195// attr returns the current Attribute pointed to by the decoder.
196func (ad *AttributeDecoder) attr() Attribute {
197 return ad.attrs[ad.i-1]
198}
199
200// data returns the Data field of the current Attribute pointed to by the decoder.
201func (ad *AttributeDecoder) data() []byte {
202 return ad.attr().Data
203}
204
205// Err returns the first error encountered by the decoder.
206func (ad *AttributeDecoder) Err() error {
207 return ad.err
208}
209
210// String returns the string representation of the current Attribute's data.
211func (ad *AttributeDecoder) String() string {
212 if ad.err != nil {
213 return ""
214 }
215
216 return nlenc.String(ad.data())
217}
218
219// Uint8 returns the uint8 representation of the current Attribute's data.
220func (ad *AttributeDecoder) Uint8() uint8 {
221 if ad.err != nil {
222 return 0
223 }
224
225 b := ad.data()
226 if len(b) != 1 {
227 ad.err = fmt.Errorf("netlink: attribute %d is not a uint8; length: %d", ad.Type(), len(b))
228 return 0
229 }
230
231 return uint8(b[0])
232}
233
234// Uint16 returns the uint16 representation of the current Attribute's data.
235func (ad *AttributeDecoder) Uint16() uint16 {
236 if ad.err != nil {
237 return 0
238 }
239
240 b := ad.data()
241 if len(b) != 2 {
242 ad.err = fmt.Errorf("netlink: attribute %d is not a uint16; length: %d", ad.Type(), len(b))
243 return 0
244 }
245
246 return ad.ByteOrder.Uint16(b)
247}
248
249// Uint32 returns the uint32 representation of the current Attribute's data.
250func (ad *AttributeDecoder) Uint32() uint32 {
251 if ad.err != nil {
252 return 0
253 }
254
255 b := ad.data()
256 if len(b) != 4 {
257 ad.err = fmt.Errorf("netlink: attribute %d is not a uint32; length: %d", ad.Type(), len(b))
258 return 0
259 }
260
261 return ad.ByteOrder.Uint32(b)
262}
263
264// Uint64 returns the uint64 representation of the current Attribute's data.
265func (ad *AttributeDecoder) Uint64() uint64 {
266 if ad.err != nil {
267 return 0
268 }
269
270 b := ad.data()
271 if len(b) != 8 {
272 ad.err = fmt.Errorf("netlink: attribute %d is not a uint64; length: %d", ad.Type(), len(b))
273 return 0
274 }
275
276 return ad.ByteOrder.Uint64(b)
277}
278
279// Do is a general purpose function which allows access to the current data
280// pointed to by the AttributeDecoder.
281//
282// Do can be used to allow parsing arbitrary data within the context of the
283// decoder. Do is most useful when dealing with nested attributes, attribute
284// arrays, or decoding arbitrary types (such as C structures) which don't fit
285// cleanly into a typical unsigned integer value.
286//
287// The function fn should not retain any reference to the data b outside of the
288// scope of the function.
289func (ad *AttributeDecoder) Do(fn func(b []byte) error) {
290 if ad.err != nil {
291 return
292 }
293
294 b := ad.data()
295 if err := fn(b); err != nil {
296 ad.err = err
297 }
298}
diff --git a/vendor/github.com/mdlayher/netlink/conn.go b/vendor/github.com/mdlayher/netlink/conn.go
index 5b29fd9..ec39625 100644
--- a/vendor/github.com/mdlayher/netlink/conn.go
+++ b/vendor/github.com/mdlayher/netlink/conn.go
@@ -6,6 +6,7 @@ import (
6 "math/rand" 6 "math/rand"
7 "os" 7 "os"
8 "sync/atomic" 8 "sync/atomic"
9 "time"
9 10
10 "golang.org/x/net/bpf" 11 "golang.org/x/net/bpf"
11) 12)
@@ -23,6 +24,7 @@ var (
23 errReadWriteCloserNotSupported = errors.New("raw read/write/closer not supported") 24 errReadWriteCloserNotSupported = errors.New("raw read/write/closer not supported")
24 errMulticastGroupsNotSupported = errors.New("multicast groups not supported") 25 errMulticastGroupsNotSupported = errors.New("multicast groups not supported")
25 errBPFFiltersNotSupported = errors.New("BPF filters not supported") 26 errBPFFiltersNotSupported = errors.New("BPF filters not supported")
27 errOptionsNotSupported = errors.New("options not supported")
26) 28)
27 29
28// A Conn is a connection to netlink. A Conn can be used to send and 30// A Conn is a connection to netlink. A Conn can be used to send and
@@ -42,6 +44,9 @@ type Conn struct {
42 44
43 // pid is the PID assigned by netlink. 45 // pid is the PID assigned by netlink.
44 pid uint32 46 pid uint32
47
48 // d provides debugging capabilities for a Conn if not nil.
49 d *debugger
45} 50}
46 51
47// A Socket is an operating-system specific implementation of netlink 52// A Socket is an operating-system specific implementation of netlink
@@ -49,6 +54,7 @@ type Conn struct {
49type Socket interface { 54type Socket interface {
50 Close() error 55 Close() error
51 Send(m Message) error 56 Send(m Message) error
57 SendMessages(m []Message) error
52 Receive() ([]Message, error) 58 Receive() ([]Message, error)
53} 59}
54 60
@@ -71,13 +77,31 @@ func Dial(family int, config *Config) (*Conn, error) {
71// NewConn is primarily useful for tests. Most applications should use 77// NewConn is primarily useful for tests. Most applications should use
72// Dial instead. 78// Dial instead.
73func NewConn(c Socket, pid uint32) *Conn { 79func NewConn(c Socket, pid uint32) *Conn {
74 seq := rand.Uint32() 80 // Seed the sequence number using a random number generator.
81 r := rand.New(rand.NewSource(time.Now().UnixNano()))
82 seq := r.Uint32()
83
84 // Configure a debugger if arguments are set.
85 var d *debugger
86 if len(debugArgs) > 0 {
87 d = newDebugger(debugArgs)
88 }
75 89
76 return &Conn{ 90 return &Conn{
77 sock: c, 91 sock: c,
78 seq: &seq, 92 seq: &seq,
79 pid: pid, 93 pid: pid,
94 d: d,
95 }
96}
97
98// debug executes fn with the debugger if the debugger is not nil.
99func (c *Conn) debug(fn func(d *debugger)) {
100 if c.d == nil {
101 return
80 } 102 }
103
104 fn(c.d)
81} 105}
82 106
83// Close closes the connection. 107// Close closes the connection.
@@ -109,6 +133,51 @@ func (c *Conn) Execute(m Message) ([]Message, error) {
109 return replies, nil 133 return replies, nil
110} 134}
111 135
136func (c *Conn) fixMsg(m *Message, ml int) {
137 if m.Header.Length == 0 {
138 m.Header.Length = uint32(nlmsgAlign(ml))
139 }
140
141 if m.Header.Sequence == 0 {
142 m.Header.Sequence = c.nextSequence()
143 }
144
145 if m.Header.PID == 0 {
146 m.Header.PID = c.pid
147 }
148}
149
150// SendMessages sends multiple Messages to netlink. The handling of
151// m.Header.Length, Sequence and PID is the same as when calling Send.
152func (c *Conn) SendMessages(messages []Message) ([]Message, error) {
153 for idx, m := range messages {
154 ml := nlmsgLength(len(m.Data))
155
156 // TODO(mdlayher): fine-tune this limit.
157 if ml > (1024 * 32) {
158 return nil, errors.New("netlink message data too large")
159 }
160
161 c.fixMsg(&messages[idx], ml)
162 }
163
164 c.debug(func(d *debugger) {
165 for _, m := range messages {
166 d.debugf(1, "send msgs: %+v", m)
167 }
168 })
169
170 if err := c.sock.SendMessages(messages); err != nil {
171 c.debug(func(d *debugger) {
172 d.debugf(1, "send msgs: err: %v", err)
173 })
174
175 return nil, err
176 }
177
178 return messages, nil
179}
180
112// Send sends a single Message to netlink. In most cases, m.Header's Length, 181// Send sends a single Message to netlink. In most cases, m.Header's Length,
113// Sequence, and PID fields should be set to 0, so they can be populated 182// Sequence, and PID fields should be set to 0, so they can be populated
114// automatically before the Message is sent. On success, Send returns a copy 183// automatically before the Message is sent. On success, Send returns a copy
@@ -130,19 +199,17 @@ func (c *Conn) Send(m Message) (Message, error) {
130 return Message{}, errors.New("netlink message data too large") 199 return Message{}, errors.New("netlink message data too large")
131 } 200 }
132 201
133 if m.Header.Length == 0 { 202 c.fixMsg(&m, ml)
134 m.Header.Length = uint32(nlmsgAlign(ml))
135 }
136 203
137 if m.Header.Sequence == 0 { 204 c.debug(func(d *debugger) {
138 m.Header.Sequence = c.nextSequence() 205 d.debugf(1, "send: %+v", m)
139 } 206 })
140
141 if m.Header.PID == 0 {
142 m.Header.PID = c.pid
143 }
144 207
145 if err := c.sock.Send(m); err != nil { 208 if err := c.sock.Send(m); err != nil {
209 c.debug(func(d *debugger) {
210 d.debugf(1, "send: err: %v", err)
211 })
212
146 return Message{}, err 213 return Message{}, err
147 } 214 }
148 215
@@ -157,9 +224,19 @@ func (c *Conn) Send(m Message) (Message, error) {
157func (c *Conn) Receive() ([]Message, error) { 224func (c *Conn) Receive() ([]Message, error) {
158 msgs, err := c.receive() 225 msgs, err := c.receive()
159 if err != nil { 226 if err != nil {
227 c.debug(func(d *debugger) {
228 d.debugf(1, "recv: err: %v", err)
229 })
230
160 return nil, err 231 return nil, err
161 } 232 }
162 233
234 c.debug(func(d *debugger) {
235 for _, m := range msgs {
236 d.debugf(1, "recv: %+v", m)
237 }
238 })
239
163 // When using nltest, it's possible for zero messages to be returned by receive. 240 // When using nltest, it's possible for zero messages to be returned by receive.
164 if len(msgs) == 0 { 241 if len(msgs) == 0 {
165 return msgs, nil 242 return msgs, nil
@@ -177,37 +254,40 @@ func (c *Conn) Receive() ([]Message, error) {
177// receive is the internal implementation of Conn.Receive, which can be called 254// receive is the internal implementation of Conn.Receive, which can be called
178// recursively to handle multi-part messages. 255// recursively to handle multi-part messages.
179func (c *Conn) receive() ([]Message, error) { 256func (c *Conn) receive() ([]Message, error) {
180 msgs, err := c.sock.Receive() 257 var res []Message
181 if err != nil { 258 for {
182 return nil, err 259 msgs, err := c.sock.Receive()
183 } 260 if err != nil {
261 return nil, err
262 }
184 263
185 // If this message is multi-part, we will need to perform an recursive call 264 // If this message is multi-part, we will need to perform an recursive call
186 // to continue draining the socket 265 // to continue draining the socket
187 var multi bool 266 var multi bool
188 267
189 for _, m := range msgs { 268 for _, m := range msgs {
190 // Is this a multi-part message and is it not done yet? 269 if err := checkMessage(m); err != nil {
191 if m.Header.Flags&HeaderFlagsMulti != 0 && m.Header.Type != HeaderTypeDone { 270 return nil, err
192 multi = true 271 }
193 }
194 272
195 if err := checkMessage(m); err != nil { 273 // Does this message indicate a multi-part message?
196 return nil, err 274 if m.Header.Flags&HeaderFlagsMulti == 0 {
275 // No, check the next messages.
276 continue
277 }
278
279 // Does this message indicate the last message in a series of
280 // multi-part messages from a single read?
281 multi = m.Header.Type != HeaderTypeDone
197 } 282 }
198 }
199 283
200 if !multi { 284 res = append(res, msgs...)
201 return msgs, nil
202 }
203 285
204 // More messages waiting 286 if !multi {
205 mmsgs, err := c.receive() 287 // No more messages coming.
206 if err != nil { 288 return res, nil
207 return nil, err 289 }
208 } 290 }
209
210 return append(msgs, mmsgs...), nil
211} 291}
212 292
213// An fder is a Socket that supports retrieving its raw file descriptor. 293// An fder is a Socket that supports retrieving its raw file descriptor.
@@ -283,10 +363,11 @@ func (c *Conn) LeaveGroup(group uint32) error {
283 return gc.LeaveGroup(group) 363 return gc.LeaveGroup(group)
284} 364}
285 365
286// A bpfSetter is a Socket that supports setting BPF filters. 366// A bpfSetter is a Socket that supports setting and removing BPF filters.
287type bpfSetter interface { 367type bpfSetter interface {
288 Socket 368 Socket
289 bpf.Setter 369 bpf.Setter
370 RemoveBPF() error
290} 371}
291 372
292// SetBPF attaches an assembled BPF program to a Conn. 373// SetBPF attaches an assembled BPF program to a Conn.
@@ -299,6 +380,45 @@ func (c *Conn) SetBPF(filter []bpf.RawInstruction) error {
299 return bc.SetBPF(filter) 380 return bc.SetBPF(filter)
300} 381}
301 382
383// RemoveBPF removes a BPF filter from a Conn.
384func (c *Conn) RemoveBPF() error {
385 s, ok := c.sock.(bpfSetter)
386 if !ok {
387 return errBPFFiltersNotSupported
388 }
389
390 return s.RemoveBPF()
391}
392
393// A ConnOption is a boolean option that may be set for a Conn.
394type ConnOption int
395
396// Possible ConnOption values. These constants are equivalent to the Linux
397// setsockopt boolean options for netlink sockets.
398const (
399 PacketInfo ConnOption = iota
400 BroadcastError
401 NoENOBUFS
402 ListenAllNSID
403 CapAcknowledge
404)
405
406// An optionSetter is a Socket that supports setting netlink options.
407type optionSetter interface {
408 Socket
409 SetOption(option ConnOption, enable bool) error
410}
411
412// SetOption enables or disables a netlink socket option for the Conn.
413func (c *Conn) SetOption(option ConnOption, enable bool) error {
414 fc, ok := c.sock.(optionSetter)
415 if !ok {
416 return errOptionsNotSupported
417 }
418
419 return fc.SetOption(option, enable)
420}
421
302// nextSequence atomically increments Conn's sequence number and returns 422// nextSequence atomically increments Conn's sequence number and returns
303// the incremented value. 423// the incremented value.
304func (c *Conn) nextSequence() uint32 { 424func (c *Conn) nextSequence() uint32 {
diff --git a/vendor/github.com/mdlayher/netlink/conn_linux.go b/vendor/github.com/mdlayher/netlink/conn_linux.go
index 2c9e38a..691e30a 100644
--- a/vendor/github.com/mdlayher/netlink/conn_linux.go
+++ b/vendor/github.com/mdlayher/netlink/conn_linux.go
@@ -94,6 +94,25 @@ func bind(s socket, config *Config) (*conn, uint32, error) {
94 }, pid, nil 94 }, pid, nil
95} 95}
96 96
97// SendMessages serializes multiple Messages and sends them to netlink.
98func (c *conn) SendMessages(messages []Message) error {
99 var buf []byte
100 for _, m := range messages {
101 b, err := m.MarshalBinary()
102 if err != nil {
103 return err
104 }
105
106 buf = append(buf, b...)
107 }
108
109 addr := &unix.SockaddrNetlink{
110 Family: unix.AF_NETLINK,
111 }
112
113 return c.s.Sendmsg(buf, nil, addr, 0)
114}
115
97// Send sends a single Message to netlink. 116// Send sends a single Message to netlink.
98func (c *conn) Send(m Message) error { 117func (c *conn) Send(m Message) error {
99 b, err := m.MarshalBinary() 118 b, err := m.MarshalBinary()
@@ -112,7 +131,10 @@ func (c *conn) Send(m Message) error {
112func (c *conn) Receive() ([]Message, error) { 131func (c *conn) Receive() ([]Message, error) {
113 b := make([]byte, os.Getpagesize()) 132 b := make([]byte, os.Getpagesize())
114 for { 133 for {
115 // Peek at the buffer to see how many bytes are available 134 // Peek at the buffer to see how many bytes are available.
135 //
136 // TODO(mdlayher): deal with OOB message data if available, such as
137 // when PacketInfo ConnOption is true.
116 n, _, _, _, err := c.s.Recvmsg(b, nil, unix.MSG_PEEK) 138 n, _, _, _, err := c.s.Recvmsg(b, nil, unix.MSG_PEEK)
117 if err != nil { 139 if err != nil {
118 return nil, err 140 return nil, err
@@ -204,6 +226,58 @@ func (c *conn) SetBPF(filter []bpf.RawInstruction) error {
204 ) 226 )
205} 227}
206 228
229// RemoveBPF removes a BPF filter from a conn.
230func (c *conn) RemoveBPF() error {
231 // dummy is ignored as argument to SO_DETACH_FILTER
232 // but SetSockopt requires it as an argument
233 var dummy uint32
234 return c.s.SetSockopt(
235 unix.SOL_SOCKET,
236 unix.SO_DETACH_FILTER,
237 unsafe.Pointer(&dummy),
238 uint32(unsafe.Sizeof(dummy)),
239 )
240}
241
242// SetOption enables or disables a netlink socket option for the Conn.
243func (c *conn) SetOption(option ConnOption, enable bool) error {
244 o, ok := linuxOption(option)
245 if !ok {
246 // Return the typical Linux error for an unknown ConnOption.
247 return unix.ENOPROTOOPT
248 }
249
250 var v uint32
251 if enable {
252 v = 1
253 }
254
255 return c.s.SetSockopt(
256 unix.SOL_NETLINK,
257 o,
258 unsafe.Pointer(&v),
259 uint32(unsafe.Sizeof(v)),
260 )
261}
262
263// linuxOption converts a ConnOption to its Linux value.
264func linuxOption(o ConnOption) (int, bool) {
265 switch o {
266 case PacketInfo:
267 return unix.NETLINK_PKTINFO, true
268 case BroadcastError:
269 return unix.NETLINK_BROADCAST_ERROR, true
270 case NoENOBUFS:
271 return unix.NETLINK_NO_ENOBUFS, true
272 case ListenAllNSID:
273 return unix.NETLINK_LISTEN_ALL_NSID, true
274 case CapAcknowledge:
275 return unix.NETLINK_CAP_ACK, true
276 default:
277 return 0, false
278 }
279}
280
207// sysToHeader converts a syscall.NlMsghdr to a Header. 281// sysToHeader converts a syscall.NlMsghdr to a Header.
208func sysToHeader(r syscall.NlMsghdr) Header { 282func sysToHeader(r syscall.NlMsghdr) Header {
209 // NB: the memory layout of Header and syscall.NlMsgHdr must be 283 // NB: the memory layout of Header and syscall.NlMsgHdr must be
@@ -247,10 +321,20 @@ func newSysSocket(lockThread bool) *sysSocket {
247 // But since this is very experimental, we'll leave it as a configurable at 321 // But since this is very experimental, we'll leave it as a configurable at
248 // this point. 322 // this point.
249 if lockThread { 323 if lockThread {
250 // Never unlock the OS thread, so that the thread will terminate when 324 // The intent is to never unlock the OS thread, so that the thread
251 // the goroutine exits starting in Go 1.10: 325 // will terminate when the goroutine exits starting in Go 1.10:
252 // https://go-review.googlesource.com/c/go/+/46038. 326 // https://go-review.googlesource.com/c/go/+/46038.
327 //
328 // However, due to recent instability and a potential bad interaction
329 // with the Go runtime for threads which are not unlocked, we have
330 // elected to temporarily unlock the thread:
331 // https://github.com/golang/go/issues/25128#issuecomment-410764489.
332 //
333 // If we ever allow a Conn to set its own network namespace, we must
334 // either ensure that the namespace is restored on exit here or that
335 // the thread is properly terminated at some point in the future.
253 runtime.LockOSThread() 336 runtime.LockOSThread()
337 defer runtime.UnlockOSThread()
254 } 338 }
255 339
256 defer wg.Done() 340 defer wg.Done()
diff --git a/vendor/github.com/mdlayher/netlink/conn_others.go b/vendor/github.com/mdlayher/netlink/conn_others.go
index de94a96..447aaa5 100644
--- a/vendor/github.com/mdlayher/netlink/conn_others.go
+++ b/vendor/github.com/mdlayher/netlink/conn_others.go
@@ -5,14 +5,12 @@ package netlink
5import ( 5import (
6 "fmt" 6 "fmt"
7 "runtime" 7 "runtime"
8
9 "golang.org/x/net/bpf"
10) 8)
11 9
12var ( 10var (
13 // errUnimplemented is returned by all functions on platforms that 11 // errUnimplemented is returned by all functions on platforms that
14 // cannot make use of netlink sockets. 12 // cannot make use of netlink sockets.
15 errUnimplemented = fmt.Errorf("netlink sockets not implemented on %s/%s", 13 errUnimplemented = fmt.Errorf("netlink: not implemented on %s/%s",
16 runtime.GOOS, runtime.GOARCH) 14 runtime.GOOS, runtime.GOARCH)
17) 15)
18 16
@@ -21,42 +19,13 @@ var _ Socket = &conn{}
21// A conn is the no-op implementation of a netlink sockets connection. 19// A conn is the no-op implementation of a netlink sockets connection.
22type conn struct{} 20type conn struct{}
23 21
24// dial is the entry point for Dial. dial always returns an error. 22// All cross-platform functions and Socket methods are unimplemented outside
25func dial(family int, config *Config) (*conn, uint32, error) { 23// of Linux.
26 return nil, 0, errUnimplemented 24
27} 25func dial(_ int, _ *Config) (*conn, uint32, error) { return nil, 0, errUnimplemented }
28 26func newError(_ int) error { return errUnimplemented }
29// Send always returns an error. 27
30func (c *conn) Send(m Message) error { 28func (c *conn) Send(_ Message) error { return errUnimplemented }
31 return errUnimplemented 29func (c *conn) SendMessages(_ []Message) error { return errUnimplemented }
32} 30func (c *conn) Receive() ([]Message, error) { return nil, errUnimplemented }
33 31func (c *conn) Close() error { return errUnimplemented }
34// Receive always returns an error.
35func (c *conn) Receive() ([]Message, error) {
36 return nil, errUnimplemented
37}
38
39// Close always returns an error.
40func (c *conn) Close() error {
41 return errUnimplemented
42}
43
44// JoinGroup always returns an error.
45func (c *conn) JoinGroup(group uint32) error {
46 return errUnimplemented
47}
48
49// LeaveGroup always returns an error.
50func (c *conn) LeaveGroup(group uint32) error {
51 return errUnimplemented
52}
53
54// SetBPF always returns an error.
55func (c *conn) SetBPF(filter []bpf.RawInstruction) error {
56 return errUnimplemented
57}
58
59// newError always returns an error.
60func newError(errno int) error {
61 return errUnimplemented
62}
diff --git a/vendor/github.com/mdlayher/netlink/debug.go b/vendor/github.com/mdlayher/netlink/debug.go
new file mode 100644
index 0000000..3d2e05a
--- /dev/null
+++ b/vendor/github.com/mdlayher/netlink/debug.go
@@ -0,0 +1,71 @@
1package netlink
2
3import (
4 "fmt"
5 "log"
6 "os"
7 "strconv"
8 "strings"
9)
10
11var (
12 // Arguments used to create a debugger.
13 debugArgs []string
14)
15
16func init() {
17 // Is netlink debugging enabled?
18 s := os.Getenv("NLDEBUG")
19 if s == "" {
20 return
21 }
22
23 debugArgs = strings.Split(s, ",")
24}
25
26// A debugger is used to provide debugging information about a netlink connection.
27type debugger struct {
28 Log *log.Logger
29 Level int
30}
31
32// newDebugger creates a debugger by parsing key=value arguments.
33func newDebugger(args []string) *debugger {
34 d := &debugger{
35 Log: log.New(os.Stderr, "nl: ", 0),
36 Level: 1,
37 }
38
39 for _, a := range args {
40 kv := strings.Split(a, "=")
41 if len(kv) != 2 {
42 // Ignore malformed pairs and assume callers wants defaults.
43 continue
44 }
45
46 switch kv[0] {
47 // Select the log level for the debugger.
48 case "level":
49 level, err := strconv.Atoi(kv[1])
50 if err != nil {
51 panicf("netlink: invalid NLDEBUG level: %q", a)
52 }
53
54 d.Level = level
55 }
56 }
57
58 return d
59}
60
61// debugf prints debugging information at the specified level, if d.Level is
62// high enough to print the message.
63func (d *debugger) debugf(level int, format string, v ...interface{}) {
64 if d.Level >= level {
65 d.Log.Printf(format, v...)
66 }
67}
68
69func panicf(format string, a ...interface{}) {
70 panic(fmt.Sprintf(format, a...))
71}
diff --git a/vendor/github.com/mdlayher/netlink/doc.go b/vendor/github.com/mdlayher/netlink/doc.go
index 73e8c11..0768be2 100644
--- a/vendor/github.com/mdlayher/netlink/doc.go
+++ b/vendor/github.com/mdlayher/netlink/doc.go
@@ -1,2 +1,22 @@
1// Package netlink provides low-level access to Linux netlink sockets. 1// Package netlink provides low-level access to Linux netlink sockets.
2//
3//
4// Debugging
5//
6// This package supports rudimentary netlink connection debugging support.
7// To enable this, run your binary with the NLDEBUG environment variable set.
8// Debugging information will be output to stderr with a prefix of "nl:".
9//
10// To use the debugging defaults, use:
11//
12// $ NLDEBUG=1 ./nlctl
13//
14// To configure individual aspects of the debugger, pass key/value options such
15// as:
16//
17// $ NLDEBUG=level=1 ./nlctl
18//
19// Available key/value debugger options include:
20//
21// level=N: specify the debugging level (only "1" is currently supported)
2package netlink 22package netlink
diff --git a/vendor/github.com/mdlayher/netlink/nlenc/endian.go b/vendor/github.com/mdlayher/netlink/nlenc/endian.go
new file mode 100644
index 0000000..332f487
--- /dev/null
+++ b/vendor/github.com/mdlayher/netlink/nlenc/endian.go
@@ -0,0 +1,16 @@
1package nlenc
2
3import (
4 "encoding/binary"
5)
6
7// NativeEndian returns the native byte order of this system.
8func NativeEndian() binary.ByteOrder {
9 // Determine endianness by storing a uint16 in a byte slice.
10 b := Uint16Bytes(1)
11 if b[0] == 1 {
12 return binary.LittleEndian
13 }
14
15 return binary.BigEndian
16}
diff --git a/vendor/vendor.json b/vendor/vendor.json
index c8cad52..02667b6 100644
--- a/vendor/vendor.json
+++ b/vendor/vendor.json
@@ -85,28 +85,28 @@
85 "versionExact": "v1.0.0" 85 "versionExact": "v1.0.0"
86 }, 86 },
87 { 87 {
88 "checksumSHA1": "VZIJG8dML/XqZbL9bpeDNgkazcg=", 88 "checksumSHA1": "zLH8BV9kYzpqGB5PS4VDjADFvVM=",
89 "path": "github.com/mdlayher/genetlink", 89 "path": "github.com/mdlayher/genetlink",
90 "revision": "76fecce4c787fb8eaa21a8755f722d67c53038e1", 90 "revision": "ca85b5a307448462b0aa7a07c67c0846bc12568f",
91 "revisionTime": "2017-09-01T18:19:24Z" 91 "revisionTime": "2018-07-28T17:03:40Z"
92 }, 92 },
93 { 93 {
94 "checksumSHA1": "S6NatJYh1aOFzSIs6Agp2R0ydtM=", 94 "checksumSHA1": "ybkJbYD6wyjdoPp/KncnDpCyYiU=",
95 "path": "github.com/mdlayher/netlink", 95 "path": "github.com/mdlayher/netlink",
96 "revision": "756e798fb38fac19fb2234d3acc32e902bc1af44", 96 "revision": "80a6f93efd374ddee4e0ea862ca0085ef42eed65",
97 "revisionTime": "2017-12-14T18:12:53Z" 97 "revisionTime": "2018-08-10T15:28:04Z"
98 }, 98 },
99 { 99 {
100 "checksumSHA1": "9nig0WuuiTICStI/8S+pIGqYksc=", 100 "checksumSHA1": "P7eEo2V7/kQEkt2ihW+26S39eEw=",
101 "path": "github.com/mdlayher/netlink/nlenc", 101 "path": "github.com/mdlayher/netlink/nlenc",
102 "revision": "756e798fb38fac19fb2234d3acc32e902bc1af44", 102 "revision": "80a6f93efd374ddee4e0ea862ca0085ef42eed65",
103 "revisionTime": "2017-12-14T18:12:53Z" 103 "revisionTime": "2018-08-10T15:28:04Z"
104 }, 104 },
105 { 105 {
106 "checksumSHA1": "Y7cjrOeOvA/ic+B8WCp2JyLEuvs=", 106 "checksumSHA1": "Y7cjrOeOvA/ic+B8WCp2JyLEuvs=",
107 "path": "github.com/mdlayher/wifi", 107 "path": "github.com/mdlayher/wifi",
108 "revision": "9a2549315201616119128afe421d1601ef3506f9", 108 "revision": "efdf3f4195d9fc8b73013b3706fe626b7fb807d8",
109 "revisionTime": "2018-06-15T12:49:15Z" 109 "revisionTime": "2018-07-27T16:38:19Z"
110 }, 110 },
111 { 111 {
112 "checksumSHA1": "VzutdH69PUqRqhrDVv6F91ebQd4=", 112 "checksumSHA1": "VzutdH69PUqRqhrDVv6F91ebQd4=",