diff options
author | Matt Layher <mdlayher@gmail.com> | 2018-08-14 15:15:07 -0400 |
---|---|---|
committer | Ben Kochie <superq@gmail.com> | 2018-08-14 21:15:07 +0200 |
commit | d84873727f7679b2d782ecd27f3cc8ecd365457f (patch) | |
tree | d6704b3d92e130d10ced23df90350a6aaac59396 | |
parent | 60c827231afe2a7621ee632e02c3dd94e0faa19f (diff) | |
download | prometheus_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.go | 10 | ||||
-rw-r--r-- | vendor/github.com/mdlayher/genetlink/family_linux.go | 94 | ||||
-rw-r--r-- | vendor/github.com/mdlayher/netlink/attribute.go | 222 | ||||
-rw-r--r-- | vendor/github.com/mdlayher/netlink/conn.go | 192 | ||||
-rw-r--r-- | vendor/github.com/mdlayher/netlink/conn_linux.go | 90 | ||||
-rw-r--r-- | vendor/github.com/mdlayher/netlink/conn_others.go | 53 | ||||
-rw-r--r-- | vendor/github.com/mdlayher/netlink/debug.go | 71 | ||||
-rw-r--r-- | vendor/github.com/mdlayher/netlink/doc.go | 20 | ||||
-rw-r--r-- | vendor/github.com/mdlayher/netlink/nlenc/endian.go | 16 | ||||
-rw-r--r-- | vendor/vendor.json | 22 |
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. | ||
71 | func (c *Conn) RemoveBPF() error { | ||
72 | return c.c.RemoveBPF() | ||
73 | } | ||
74 | |||
75 | // SetOption enables or disables a netlink socket option for the Conn. | ||
76 | func (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) { | |||
85 | func buildFamilies(msgs []Message) ([]Family, error) { | 81 | func 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. |
105 | func (f *Family) parseAttributes(attrs []netlink.Attribute) error { | 96 | func (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. |
134 | func parseMulticastGroups(b []byte) ([]MulticastGroup, error) { | 133 | func 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 @@ | |||
1 | package netlink | 1 | package netlink |
2 | 2 | ||
3 | import ( | 3 | import ( |
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 ( | |||
9 | var ( | 11 | var ( |
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 | ||
40 | const nlaNested uint16 = 0x8000 | ||
41 | |||
42 | // #define NLA_F_NET_BYTE_ORDER | ||
43 | const nlaNetByteOrder uint16 = 0x4000 | ||
44 | |||
45 | // Masks all bits except for Nested and NetByteOrder. | ||
46 | const nlaTypeMask = ^(nlaNested | nlaNetByteOrder) | ||
47 | |||
48 | // MarshalBinary marshals an Attribute into a byte slice. | 29 | // MarshalBinary marshals an Attribute into a byte slice. |
49 | func (a Attribute) MarshalBinary() ([]byte, error) { | 30 | func (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. | ||
142 | func UnmarshalAttributes(b []byte) ([]Attribute, error) { | 104 | func 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. | ||
138 | type 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. | ||
157 | func 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. | ||
173 | func (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. | ||
191 | func (ad *AttributeDecoder) Type() uint16 { | ||
192 | return ad.attr().Type | ||
193 | } | ||
194 | |||
195 | // attr returns the current Attribute pointed to by the decoder. | ||
196 | func (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. | ||
201 | func (ad *AttributeDecoder) data() []byte { | ||
202 | return ad.attr().Data | ||
203 | } | ||
204 | |||
205 | // Err returns the first error encountered by the decoder. | ||
206 | func (ad *AttributeDecoder) Err() error { | ||
207 | return ad.err | ||
208 | } | ||
209 | |||
210 | // String returns the string representation of the current Attribute's data. | ||
211 | func (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. | ||
220 | func (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. | ||
235 | func (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. | ||
250 | func (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. | ||
265 | func (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. | ||
289 | func (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 { | |||
49 | type Socket interface { | 54 | type 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. |
73 | func NewConn(c Socket, pid uint32) *Conn { | 79 | func 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. | ||
99 | func (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 | ||
136 | func (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. | ||
152 | func (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) { | |||
157 | func (c *Conn) Receive() ([]Message, error) { | 224 | func (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. |
179 | func (c *Conn) receive() ([]Message, error) { | 256 | func (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. |
287 | type bpfSetter interface { | 367 | type 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. | ||
384 | func (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. | ||
394 | type ConnOption int | ||
395 | |||
396 | // Possible ConnOption values. These constants are equivalent to the Linux | ||
397 | // setsockopt boolean options for netlink sockets. | ||
398 | const ( | ||
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. | ||
407 | type 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. | ||
413 | func (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. |
304 | func (c *Conn) nextSequence() uint32 { | 424 | func (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. | ||
98 | func (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. |
98 | func (c *conn) Send(m Message) error { | 117 | func (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 { | |||
112 | func (c *conn) Receive() ([]Message, error) { | 131 | func (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. | ||
230 | func (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. | ||
243 | func (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. | ||
264 | func 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. |
208 | func sysToHeader(r syscall.NlMsghdr) Header { | 282 | func 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 | |||
5 | import ( | 5 | import ( |
6 | "fmt" | 6 | "fmt" |
7 | "runtime" | 7 | "runtime" |
8 | |||
9 | "golang.org/x/net/bpf" | ||
10 | ) | 8 | ) |
11 | 9 | ||
12 | var ( | 10 | var ( |
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. |
22 | type conn struct{} | 20 | type 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 |
25 | func dial(family int, config *Config) (*conn, uint32, error) { | 23 | // of Linux. |
26 | return nil, 0, errUnimplemented | 24 | |
27 | } | 25 | func dial(_ int, _ *Config) (*conn, uint32, error) { return nil, 0, errUnimplemented } |
28 | 26 | func newError(_ int) error { return errUnimplemented } | |
29 | // Send always returns an error. | 27 | |
30 | func (c *conn) Send(m Message) error { | 28 | func (c *conn) Send(_ Message) error { return errUnimplemented } |
31 | return errUnimplemented | 29 | func (c *conn) SendMessages(_ []Message) error { return errUnimplemented } |
32 | } | 30 | func (c *conn) Receive() ([]Message, error) { return nil, errUnimplemented } |
33 | 31 | func (c *conn) Close() error { return errUnimplemented } | |
34 | // Receive always returns an error. | ||
35 | func (c *conn) Receive() ([]Message, error) { | ||
36 | return nil, errUnimplemented | ||
37 | } | ||
38 | |||
39 | // Close always returns an error. | ||
40 | func (c *conn) Close() error { | ||
41 | return errUnimplemented | ||
42 | } | ||
43 | |||
44 | // JoinGroup always returns an error. | ||
45 | func (c *conn) JoinGroup(group uint32) error { | ||
46 | return errUnimplemented | ||
47 | } | ||
48 | |||
49 | // LeaveGroup always returns an error. | ||
50 | func (c *conn) LeaveGroup(group uint32) error { | ||
51 | return errUnimplemented | ||
52 | } | ||
53 | |||
54 | // SetBPF always returns an error. | ||
55 | func (c *conn) SetBPF(filter []bpf.RawInstruction) error { | ||
56 | return errUnimplemented | ||
57 | } | ||
58 | |||
59 | // newError always returns an error. | ||
60 | func 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 @@ | |||
1 | package netlink | ||
2 | |||
3 | import ( | ||
4 | "fmt" | ||
5 | "log" | ||
6 | "os" | ||
7 | "strconv" | ||
8 | "strings" | ||
9 | ) | ||
10 | |||
11 | var ( | ||
12 | // Arguments used to create a debugger. | ||
13 | debugArgs []string | ||
14 | ) | ||
15 | |||
16 | func 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. | ||
27 | type debugger struct { | ||
28 | Log *log.Logger | ||
29 | Level int | ||
30 | } | ||
31 | |||
32 | // newDebugger creates a debugger by parsing key=value arguments. | ||
33 | func 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. | ||
63 | func (d *debugger) debugf(level int, format string, v ...interface{}) { | ||
64 | if d.Level >= level { | ||
65 | d.Log.Printf(format, v...) | ||
66 | } | ||
67 | } | ||
68 | |||
69 | func 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) | ||
2 | package netlink | 22 | package 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 @@ | |||
1 | package nlenc | ||
2 | |||
3 | import ( | ||
4 | "encoding/binary" | ||
5 | ) | ||
6 | |||
7 | // NativeEndian returns the native byte order of this system. | ||
8 | func 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=", |