mirror of
https://github.com/prometheus/node_exporter.git
synced 2024-11-09 23:24:09 -08:00
vendor: bump github.com/mdlayher/wifi and dependencies (#1045)
Signed-off-by: Matt Layher <mdlayher@gmail.com>
This commit is contained in:
parent
60c827231a
commit
d84873727f
10
vendor/github.com/mdlayher/genetlink/conn.go
generated
vendored
10
vendor/github.com/mdlayher/genetlink/conn.go
generated
vendored
|
@ -67,6 +67,16 @@ func (c *Conn) SetBPF(filter []bpf.RawInstruction) error {
|
|||
return c.c.SetBPF(filter)
|
||||
}
|
||||
|
||||
// RemoveBPF removes a BPF filter from a Conn.
|
||||
func (c *Conn) RemoveBPF() error {
|
||||
return c.c.RemoveBPF()
|
||||
}
|
||||
|
||||
// SetOption enables or disables a netlink socket option for the Conn.
|
||||
func (c *Conn) SetOption(option netlink.ConnOption, enable bool) error {
|
||||
return c.c.SetOption(option, enable)
|
||||
}
|
||||
|
||||
// Send sends a single Message to netlink, wrapping it in a netlink.Message
|
||||
// using the specified generic netlink family and flags. On success, Send
|
||||
// returns a copy of the netlink.Message with all parameters populated, for
|
||||
|
|
96
vendor/github.com/mdlayher/genetlink/family_linux.go
generated
vendored
96
vendor/github.com/mdlayher/genetlink/family_linux.go
generated
vendored
|
@ -16,10 +16,6 @@ var (
|
|||
// errInvalidFamilyVersion is returned when a family's version is greater
|
||||
// than an 8-bit integer.
|
||||
errInvalidFamilyVersion = errors.New("invalid family version attribute")
|
||||
|
||||
// errInvalidMulticastGroupArray is returned when a multicast group array
|
||||
// of attributes is malformed.
|
||||
errInvalidMulticastGroupArray = errors.New("invalid multicast group attribute array")
|
||||
)
|
||||
|
||||
// getFamily retrieves a generic netlink family with the specified name.
|
||||
|
@ -85,13 +81,8 @@ func (c *Conn) listFamilies() ([]Family, error) {
|
|||
func buildFamilies(msgs []Message) ([]Family, error) {
|
||||
families := make([]Family, 0, len(msgs))
|
||||
for _, m := range msgs {
|
||||
attrs, err := netlink.UnmarshalAttributes(m.Data)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var f Family
|
||||
if err := (&f).parseAttributes(attrs); err != nil {
|
||||
if err := (&f).parseAttributes(m.Data); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
|
@ -101,66 +92,79 @@ func buildFamilies(msgs []Message) ([]Family, error) {
|
|||
return families, nil
|
||||
}
|
||||
|
||||
// parseAttributes parses netlink attributes into a Family's fields.
|
||||
func (f *Family) parseAttributes(attrs []netlink.Attribute) error {
|
||||
for _, a := range attrs {
|
||||
switch a.Type {
|
||||
// parseAttributes decodes netlink attributes into a Family's fields.
|
||||
func (f *Family) parseAttributes(b []byte) error {
|
||||
ad, err := netlink.NewAttributeDecoder(b)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for ad.Next() {
|
||||
switch ad.Type() {
|
||||
case unix.CTRL_ATTR_FAMILY_ID:
|
||||
f.ID = nlenc.Uint16(a.Data)
|
||||
f.ID = ad.Uint16()
|
||||
case unix.CTRL_ATTR_FAMILY_NAME:
|
||||
f.Name = nlenc.String(a.Data)
|
||||
f.Name = ad.String()
|
||||
case unix.CTRL_ATTR_VERSION:
|
||||
v := nlenc.Uint32(a.Data)
|
||||
v := ad.Uint32()
|
||||
if v > math.MaxUint8 {
|
||||
return errInvalidFamilyVersion
|
||||
}
|
||||
|
||||
f.Version = uint8(v)
|
||||
case unix.CTRL_ATTR_MCAST_GROUPS:
|
||||
groups, err := parseMulticastGroups(a.Data)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
ad.Do(func(b []byte) error {
|
||||
groups, err := parseMulticastGroups(b)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
f.Groups = groups
|
||||
f.Groups = groups
|
||||
return nil
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
return ad.Err()
|
||||
}
|
||||
|
||||
// parseMulticastGroups parses an array of multicast group nested attributes
|
||||
// into a slice of MulticastGroups.
|
||||
func parseMulticastGroups(b []byte) ([]MulticastGroup, error) {
|
||||
attrs, err := netlink.UnmarshalAttributes(b)
|
||||
ad, err := netlink.NewAttributeDecoder(b)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
groups := make([]MulticastGroup, 0, len(attrs))
|
||||
for i, a := range attrs {
|
||||
// The type attribute is essentially an array index here; it starts
|
||||
// at 1 and should increment for each new array element
|
||||
if int(a.Type) != i+1 {
|
||||
return nil, errInvalidMulticastGroupArray
|
||||
}
|
||||
|
||||
nattrs, err := netlink.UnmarshalAttributes(a.Data)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var g MulticastGroup
|
||||
for _, na := range nattrs {
|
||||
switch na.Type {
|
||||
case unix.CTRL_ATTR_MCAST_GRP_NAME:
|
||||
g.Name = nlenc.String(na.Data)
|
||||
case unix.CTRL_ATTR_MCAST_GRP_ID:
|
||||
g.ID = nlenc.Uint32(na.Data)
|
||||
var groups []MulticastGroup
|
||||
for ad.Next() {
|
||||
ad.Do(func(b []byte) error {
|
||||
adi, err := netlink.NewAttributeDecoder(b)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
groups = append(groups, g)
|
||||
var g MulticastGroup
|
||||
for adi.Next() {
|
||||
switch adi.Type() {
|
||||
case unix.CTRL_ATTR_MCAST_GRP_NAME:
|
||||
g.Name = adi.String()
|
||||
case unix.CTRL_ATTR_MCAST_GRP_ID:
|
||||
g.ID = adi.Uint32()
|
||||
}
|
||||
}
|
||||
|
||||
if err := ad.Err(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
groups = append(groups, g)
|
||||
return nil
|
||||
})
|
||||
}
|
||||
|
||||
if err := ad.Err(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return groups, nil
|
||||
|
|
222
vendor/github.com/mdlayher/netlink/attribute.go
generated
vendored
222
vendor/github.com/mdlayher/netlink/attribute.go
generated
vendored
|
@ -1,7 +1,9 @@
|
|||
package netlink
|
||||
|
||||
import (
|
||||
"encoding/binary"
|
||||
"errors"
|
||||
"fmt"
|
||||
|
||||
"github.com/mdlayher/netlink/nlenc"
|
||||
)
|
||||
|
@ -9,9 +11,6 @@ import (
|
|||
var (
|
||||
// errInvalidAttribute specifies if an Attribute's length is incorrect.
|
||||
errInvalidAttribute = errors.New("invalid attribute; length too short or too large")
|
||||
// errInvalidAttributeFlags specifies if an Attribute's flag configuration is invalid.
|
||||
// From a comment in Linux/include/uapi/linux/netlink.h, Nested and NetByteOrder are mutually exclusive.
|
||||
errInvalidAttributeFlags = errors.New("invalid attribute; type cannot have both nested and net byte order flags")
|
||||
)
|
||||
|
||||
// An Attribute is a netlink attribute. Attributes are packed and unpacked
|
||||
|
@ -25,48 +24,18 @@ type Attribute struct {
|
|||
|
||||
// An arbitrary payload which is specified by Type.
|
||||
Data []byte
|
||||
|
||||
// Whether the attribute's data contains nested attributes. Note that not
|
||||
// all netlink families set this value. The programmer should consult
|
||||
// documentation and inspect an attribute's data to determine if nested
|
||||
// attributes are present.
|
||||
Nested bool
|
||||
|
||||
// Whether the attribute's data is in network (true) or native (false) byte order.
|
||||
NetByteOrder bool
|
||||
}
|
||||
|
||||
// #define NLA_F_NESTED
|
||||
const nlaNested uint16 = 0x8000
|
||||
|
||||
// #define NLA_F_NET_BYTE_ORDER
|
||||
const nlaNetByteOrder uint16 = 0x4000
|
||||
|
||||
// Masks all bits except for Nested and NetByteOrder.
|
||||
const nlaTypeMask = ^(nlaNested | nlaNetByteOrder)
|
||||
|
||||
// MarshalBinary marshals an Attribute into a byte slice.
|
||||
func (a Attribute) MarshalBinary() ([]byte, error) {
|
||||
if int(a.Length) < nlaHeaderLen {
|
||||
return nil, errInvalidAttribute
|
||||
}
|
||||
|
||||
if a.NetByteOrder && a.Nested {
|
||||
return nil, errInvalidAttributeFlags
|
||||
}
|
||||
|
||||
b := make([]byte, nlaAlign(int(a.Length)))
|
||||
|
||||
nlenc.PutUint16(b[0:2], a.Length)
|
||||
|
||||
switch {
|
||||
case a.Nested:
|
||||
nlenc.PutUint16(b[2:4], a.Type|nlaNested)
|
||||
case a.NetByteOrder:
|
||||
nlenc.PutUint16(b[2:4], a.Type|nlaNetByteOrder)
|
||||
default:
|
||||
nlenc.PutUint16(b[2:4], a.Type)
|
||||
}
|
||||
nlenc.PutUint16(b[2:4], a.Type)
|
||||
|
||||
copy(b[nlaHeaderLen:], a.Data)
|
||||
|
||||
|
@ -80,22 +49,12 @@ func (a *Attribute) UnmarshalBinary(b []byte) error {
|
|||
}
|
||||
|
||||
a.Length = nlenc.Uint16(b[0:2])
|
||||
|
||||
// Only hold the rightmost 14 bits in Type
|
||||
a.Type = nlenc.Uint16(b[2:4]) & nlaTypeMask
|
||||
|
||||
// Boolean flags extracted from the two leftmost bits of Type
|
||||
a.Nested = (nlenc.Uint16(b[2:4]) & nlaNested) > 0
|
||||
a.NetByteOrder = (nlenc.Uint16(b[2:4]) & nlaNetByteOrder) > 0
|
||||
a.Type = nlenc.Uint16(b[2:4])
|
||||
|
||||
if nlaAlign(int(a.Length)) > len(b) {
|
||||
return errInvalidAttribute
|
||||
}
|
||||
|
||||
if a.NetByteOrder && a.Nested {
|
||||
return errInvalidAttributeFlags
|
||||
}
|
||||
|
||||
switch {
|
||||
// No length, no data
|
||||
case a.Length == 0:
|
||||
|
@ -139,6 +98,9 @@ func MarshalAttributes(attrs []Attribute) ([]byte, error) {
|
|||
}
|
||||
|
||||
// UnmarshalAttributes unpacks a slice of Attributes from a single byte slice.
|
||||
//
|
||||
// It is recommend to use the AttributeDecoder type where possible instead of calling
|
||||
// UnmarshalAttributes and using package nlenc functions directly.
|
||||
func UnmarshalAttributes(b []byte) ([]Attribute, error) {
|
||||
var attrs []Attribute
|
||||
var i int
|
||||
|
@ -164,3 +126,173 @@ func UnmarshalAttributes(b []byte) ([]Attribute, error) {
|
|||
|
||||
return attrs, nil
|
||||
}
|
||||
|
||||
// An AttributeDecoder provides a safe, iterator-like, API around attribute
|
||||
// decoding.
|
||||
//
|
||||
// It is recommend to use an AttributeDecoder where possible instead of calling
|
||||
// UnmarshalAttributes and using package nlenc functions directly.
|
||||
//
|
||||
// The Err method must be called after the Next method returns false to determine
|
||||
// if any errors occurred during iteration.
|
||||
type AttributeDecoder struct {
|
||||
// ByteOrder defines a specific byte order to use when processing integer
|
||||
// attributes. ByteOrder should be set immediately after creating the
|
||||
// AttributeDecoder: before any attributes are parsed.
|
||||
//
|
||||
// If not set, the native byte order will be used.
|
||||
ByteOrder binary.ByteOrder
|
||||
|
||||
// The attributes being worked on, and the iterator index into the slice of
|
||||
// attributes.
|
||||
attrs []Attribute
|
||||
i int
|
||||
|
||||
// Any error encountered while decoding attributes.
|
||||
err error
|
||||
}
|
||||
|
||||
// NewAttributeDecoder creates an AttributeDecoder that unpacks Attributes
|
||||
// from b and prepares the decoder for iteration.
|
||||
func NewAttributeDecoder(b []byte) (*AttributeDecoder, error) {
|
||||
attrs, err := UnmarshalAttributes(b)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &AttributeDecoder{
|
||||
// By default, use native byte order.
|
||||
ByteOrder: nlenc.NativeEndian(),
|
||||
|
||||
attrs: attrs,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// Next advances the decoder to the next netlink attribute. It returns false
|
||||
// when no more attributes are present, or an error was encountered.
|
||||
func (ad *AttributeDecoder) Next() bool {
|
||||
if ad.err != nil {
|
||||
// Hit an error, stop iteration.
|
||||
return false
|
||||
}
|
||||
|
||||
ad.i++
|
||||
|
||||
if len(ad.attrs) < ad.i {
|
||||
// No more attributes, stop iteration.
|
||||
return false
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
// Type returns the Attribute.Type field of the current netlink attribute
|
||||
// pointed to by the decoder.
|
||||
func (ad *AttributeDecoder) Type() uint16 {
|
||||
return ad.attr().Type
|
||||
}
|
||||
|
||||
// attr returns the current Attribute pointed to by the decoder.
|
||||
func (ad *AttributeDecoder) attr() Attribute {
|
||||
return ad.attrs[ad.i-1]
|
||||
}
|
||||
|
||||
// data returns the Data field of the current Attribute pointed to by the decoder.
|
||||
func (ad *AttributeDecoder) data() []byte {
|
||||
return ad.attr().Data
|
||||
}
|
||||
|
||||
// Err returns the first error encountered by the decoder.
|
||||
func (ad *AttributeDecoder) Err() error {
|
||||
return ad.err
|
||||
}
|
||||
|
||||
// String returns the string representation of the current Attribute's data.
|
||||
func (ad *AttributeDecoder) String() string {
|
||||
if ad.err != nil {
|
||||
return ""
|
||||
}
|
||||
|
||||
return nlenc.String(ad.data())
|
||||
}
|
||||
|
||||
// Uint8 returns the uint8 representation of the current Attribute's data.
|
||||
func (ad *AttributeDecoder) Uint8() uint8 {
|
||||
if ad.err != nil {
|
||||
return 0
|
||||
}
|
||||
|
||||
b := ad.data()
|
||||
if len(b) != 1 {
|
||||
ad.err = fmt.Errorf("netlink: attribute %d is not a uint8; length: %d", ad.Type(), len(b))
|
||||
return 0
|
||||
}
|
||||
|
||||
return uint8(b[0])
|
||||
}
|
||||
|
||||
// Uint16 returns the uint16 representation of the current Attribute's data.
|
||||
func (ad *AttributeDecoder) Uint16() uint16 {
|
||||
if ad.err != nil {
|
||||
return 0
|
||||
}
|
||||
|
||||
b := ad.data()
|
||||
if len(b) != 2 {
|
||||
ad.err = fmt.Errorf("netlink: attribute %d is not a uint16; length: %d", ad.Type(), len(b))
|
||||
return 0
|
||||
}
|
||||
|
||||
return ad.ByteOrder.Uint16(b)
|
||||
}
|
||||
|
||||
// Uint32 returns the uint32 representation of the current Attribute's data.
|
||||
func (ad *AttributeDecoder) Uint32() uint32 {
|
||||
if ad.err != nil {
|
||||
return 0
|
||||
}
|
||||
|
||||
b := ad.data()
|
||||
if len(b) != 4 {
|
||||
ad.err = fmt.Errorf("netlink: attribute %d is not a uint32; length: %d", ad.Type(), len(b))
|
||||
return 0
|
||||
}
|
||||
|
||||
return ad.ByteOrder.Uint32(b)
|
||||
}
|
||||
|
||||
// Uint64 returns the uint64 representation of the current Attribute's data.
|
||||
func (ad *AttributeDecoder) Uint64() uint64 {
|
||||
if ad.err != nil {
|
||||
return 0
|
||||
}
|
||||
|
||||
b := ad.data()
|
||||
if len(b) != 8 {
|
||||
ad.err = fmt.Errorf("netlink: attribute %d is not a uint64; length: %d", ad.Type(), len(b))
|
||||
return 0
|
||||
}
|
||||
|
||||
return ad.ByteOrder.Uint64(b)
|
||||
}
|
||||
|
||||
// Do is a general purpose function which allows access to the current data
|
||||
// pointed to by the AttributeDecoder.
|
||||
//
|
||||
// Do can be used to allow parsing arbitrary data within the context of the
|
||||
// decoder. Do is most useful when dealing with nested attributes, attribute
|
||||
// arrays, or decoding arbitrary types (such as C structures) which don't fit
|
||||
// cleanly into a typical unsigned integer value.
|
||||
//
|
||||
// The function fn should not retain any reference to the data b outside of the
|
||||
// scope of the function.
|
||||
func (ad *AttributeDecoder) Do(fn func(b []byte) error) {
|
||||
if ad.err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
b := ad.data()
|
||||
if err := fn(b); err != nil {
|
||||
ad.err = err
|
||||
}
|
||||
}
|
||||
|
|
196
vendor/github.com/mdlayher/netlink/conn.go
generated
vendored
196
vendor/github.com/mdlayher/netlink/conn.go
generated
vendored
|
@ -6,6 +6,7 @@ import (
|
|||
"math/rand"
|
||||
"os"
|
||||
"sync/atomic"
|
||||
"time"
|
||||
|
||||
"golang.org/x/net/bpf"
|
||||
)
|
||||
|
@ -23,6 +24,7 @@ var (
|
|||
errReadWriteCloserNotSupported = errors.New("raw read/write/closer not supported")
|
||||
errMulticastGroupsNotSupported = errors.New("multicast groups not supported")
|
||||
errBPFFiltersNotSupported = errors.New("BPF filters not supported")
|
||||
errOptionsNotSupported = errors.New("options not supported")
|
||||
)
|
||||
|
||||
// A Conn is a connection to netlink. A Conn can be used to send and
|
||||
|
@ -42,6 +44,9 @@ type Conn struct {
|
|||
|
||||
// pid is the PID assigned by netlink.
|
||||
pid uint32
|
||||
|
||||
// d provides debugging capabilities for a Conn if not nil.
|
||||
d *debugger
|
||||
}
|
||||
|
||||
// A Socket is an operating-system specific implementation of netlink
|
||||
|
@ -49,6 +54,7 @@ type Conn struct {
|
|||
type Socket interface {
|
||||
Close() error
|
||||
Send(m Message) error
|
||||
SendMessages(m []Message) error
|
||||
Receive() ([]Message, error)
|
||||
}
|
||||
|
||||
|
@ -71,15 +77,33 @@ func Dial(family int, config *Config) (*Conn, error) {
|
|||
// NewConn is primarily useful for tests. Most applications should use
|
||||
// Dial instead.
|
||||
func NewConn(c Socket, pid uint32) *Conn {
|
||||
seq := rand.Uint32()
|
||||
// Seed the sequence number using a random number generator.
|
||||
r := rand.New(rand.NewSource(time.Now().UnixNano()))
|
||||
seq := r.Uint32()
|
||||
|
||||
// Configure a debugger if arguments are set.
|
||||
var d *debugger
|
||||
if len(debugArgs) > 0 {
|
||||
d = newDebugger(debugArgs)
|
||||
}
|
||||
|
||||
return &Conn{
|
||||
sock: c,
|
||||
seq: &seq,
|
||||
pid: pid,
|
||||
d: d,
|
||||
}
|
||||
}
|
||||
|
||||
// debug executes fn with the debugger if the debugger is not nil.
|
||||
func (c *Conn) debug(fn func(d *debugger)) {
|
||||
if c.d == nil {
|
||||
return
|
||||
}
|
||||
|
||||
fn(c.d)
|
||||
}
|
||||
|
||||
// Close closes the connection.
|
||||
func (c *Conn) Close() error {
|
||||
return c.sock.Close()
|
||||
|
@ -109,6 +133,51 @@ func (c *Conn) Execute(m Message) ([]Message, error) {
|
|||
return replies, nil
|
||||
}
|
||||
|
||||
func (c *Conn) fixMsg(m *Message, ml int) {
|
||||
if m.Header.Length == 0 {
|
||||
m.Header.Length = uint32(nlmsgAlign(ml))
|
||||
}
|
||||
|
||||
if m.Header.Sequence == 0 {
|
||||
m.Header.Sequence = c.nextSequence()
|
||||
}
|
||||
|
||||
if m.Header.PID == 0 {
|
||||
m.Header.PID = c.pid
|
||||
}
|
||||
}
|
||||
|
||||
// SendMessages sends multiple Messages to netlink. The handling of
|
||||
// m.Header.Length, Sequence and PID is the same as when calling Send.
|
||||
func (c *Conn) SendMessages(messages []Message) ([]Message, error) {
|
||||
for idx, m := range messages {
|
||||
ml := nlmsgLength(len(m.Data))
|
||||
|
||||
// TODO(mdlayher): fine-tune this limit.
|
||||
if ml > (1024 * 32) {
|
||||
return nil, errors.New("netlink message data too large")
|
||||
}
|
||||
|
||||
c.fixMsg(&messages[idx], ml)
|
||||
}
|
||||
|
||||
c.debug(func(d *debugger) {
|
||||
for _, m := range messages {
|
||||
d.debugf(1, "send msgs: %+v", m)
|
||||
}
|
||||
})
|
||||
|
||||
if err := c.sock.SendMessages(messages); err != nil {
|
||||
c.debug(func(d *debugger) {
|
||||
d.debugf(1, "send msgs: err: %v", err)
|
||||
})
|
||||
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return messages, nil
|
||||
}
|
||||
|
||||
// Send sends a single Message to netlink. In most cases, m.Header's Length,
|
||||
// Sequence, and PID fields should be set to 0, so they can be populated
|
||||
// automatically before the Message is sent. On success, Send returns a copy
|
||||
|
@ -130,19 +199,17 @@ func (c *Conn) Send(m Message) (Message, error) {
|
|||
return Message{}, errors.New("netlink message data too large")
|
||||
}
|
||||
|
||||
if m.Header.Length == 0 {
|
||||
m.Header.Length = uint32(nlmsgAlign(ml))
|
||||
}
|
||||
c.fixMsg(&m, ml)
|
||||
|
||||
if m.Header.Sequence == 0 {
|
||||
m.Header.Sequence = c.nextSequence()
|
||||
}
|
||||
|
||||
if m.Header.PID == 0 {
|
||||
m.Header.PID = c.pid
|
||||
}
|
||||
c.debug(func(d *debugger) {
|
||||
d.debugf(1, "send: %+v", m)
|
||||
})
|
||||
|
||||
if err := c.sock.Send(m); err != nil {
|
||||
c.debug(func(d *debugger) {
|
||||
d.debugf(1, "send: err: %v", err)
|
||||
})
|
||||
|
||||
return Message{}, err
|
||||
}
|
||||
|
||||
|
@ -157,9 +224,19 @@ func (c *Conn) Send(m Message) (Message, error) {
|
|||
func (c *Conn) Receive() ([]Message, error) {
|
||||
msgs, err := c.receive()
|
||||
if err != nil {
|
||||
c.debug(func(d *debugger) {
|
||||
d.debugf(1, "recv: err: %v", err)
|
||||
})
|
||||
|
||||
return nil, err
|
||||
}
|
||||
|
||||
c.debug(func(d *debugger) {
|
||||
for _, m := range msgs {
|
||||
d.debugf(1, "recv: %+v", m)
|
||||
}
|
||||
})
|
||||
|
||||
// When using nltest, it's possible for zero messages to be returned by receive.
|
||||
if len(msgs) == 0 {
|
||||
return msgs, nil
|
||||
|
@ -177,37 +254,40 @@ func (c *Conn) Receive() ([]Message, error) {
|
|||
// receive is the internal implementation of Conn.Receive, which can be called
|
||||
// recursively to handle multi-part messages.
|
||||
func (c *Conn) receive() ([]Message, error) {
|
||||
msgs, err := c.sock.Receive()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// If this message is multi-part, we will need to perform an recursive call
|
||||
// to continue draining the socket
|
||||
var multi bool
|
||||
|
||||
for _, m := range msgs {
|
||||
// Is this a multi-part message and is it not done yet?
|
||||
if m.Header.Flags&HeaderFlagsMulti != 0 && m.Header.Type != HeaderTypeDone {
|
||||
multi = true
|
||||
}
|
||||
|
||||
if err := checkMessage(m); err != nil {
|
||||
var res []Message
|
||||
for {
|
||||
msgs, err := c.sock.Receive()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
if !multi {
|
||||
return msgs, nil
|
||||
}
|
||||
// If this message is multi-part, we will need to perform an recursive call
|
||||
// to continue draining the socket
|
||||
var multi bool
|
||||
|
||||
// More messages waiting
|
||||
mmsgs, err := c.receive()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
for _, m := range msgs {
|
||||
if err := checkMessage(m); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return append(msgs, mmsgs...), nil
|
||||
// Does this message indicate a multi-part message?
|
||||
if m.Header.Flags&HeaderFlagsMulti == 0 {
|
||||
// No, check the next messages.
|
||||
continue
|
||||
}
|
||||
|
||||
// Does this message indicate the last message in a series of
|
||||
// multi-part messages from a single read?
|
||||
multi = m.Header.Type != HeaderTypeDone
|
||||
}
|
||||
|
||||
res = append(res, msgs...)
|
||||
|
||||
if !multi {
|
||||
// No more messages coming.
|
||||
return res, nil
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// An fder is a Socket that supports retrieving its raw file descriptor.
|
||||
|
@ -283,10 +363,11 @@ func (c *Conn) LeaveGroup(group uint32) error {
|
|||
return gc.LeaveGroup(group)
|
||||
}
|
||||
|
||||
// A bpfSetter is a Socket that supports setting BPF filters.
|
||||
// A bpfSetter is a Socket that supports setting and removing BPF filters.
|
||||
type bpfSetter interface {
|
||||
Socket
|
||||
bpf.Setter
|
||||
RemoveBPF() error
|
||||
}
|
||||
|
||||
// SetBPF attaches an assembled BPF program to a Conn.
|
||||
|
@ -299,6 +380,45 @@ func (c *Conn) SetBPF(filter []bpf.RawInstruction) error {
|
|||
return bc.SetBPF(filter)
|
||||
}
|
||||
|
||||
// RemoveBPF removes a BPF filter from a Conn.
|
||||
func (c *Conn) RemoveBPF() error {
|
||||
s, ok := c.sock.(bpfSetter)
|
||||
if !ok {
|
||||
return errBPFFiltersNotSupported
|
||||
}
|
||||
|
||||
return s.RemoveBPF()
|
||||
}
|
||||
|
||||
// A ConnOption is a boolean option that may be set for a Conn.
|
||||
type ConnOption int
|
||||
|
||||
// Possible ConnOption values. These constants are equivalent to the Linux
|
||||
// setsockopt boolean options for netlink sockets.
|
||||
const (
|
||||
PacketInfo ConnOption = iota
|
||||
BroadcastError
|
||||
NoENOBUFS
|
||||
ListenAllNSID
|
||||
CapAcknowledge
|
||||
)
|
||||
|
||||
// An optionSetter is a Socket that supports setting netlink options.
|
||||
type optionSetter interface {
|
||||
Socket
|
||||
SetOption(option ConnOption, enable bool) error
|
||||
}
|
||||
|
||||
// SetOption enables or disables a netlink socket option for the Conn.
|
||||
func (c *Conn) SetOption(option ConnOption, enable bool) error {
|
||||
fc, ok := c.sock.(optionSetter)
|
||||
if !ok {
|
||||
return errOptionsNotSupported
|
||||
}
|
||||
|
||||
return fc.SetOption(option, enable)
|
||||
}
|
||||
|
||||
// nextSequence atomically increments Conn's sequence number and returns
|
||||
// the incremented value.
|
||||
func (c *Conn) nextSequence() uint32 {
|
||||
|
|
90
vendor/github.com/mdlayher/netlink/conn_linux.go
generated
vendored
90
vendor/github.com/mdlayher/netlink/conn_linux.go
generated
vendored
|
@ -94,6 +94,25 @@ func bind(s socket, config *Config) (*conn, uint32, error) {
|
|||
}, pid, nil
|
||||
}
|
||||
|
||||
// SendMessages serializes multiple Messages and sends them to netlink.
|
||||
func (c *conn) SendMessages(messages []Message) error {
|
||||
var buf []byte
|
||||
for _, m := range messages {
|
||||
b, err := m.MarshalBinary()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
buf = append(buf, b...)
|
||||
}
|
||||
|
||||
addr := &unix.SockaddrNetlink{
|
||||
Family: unix.AF_NETLINK,
|
||||
}
|
||||
|
||||
return c.s.Sendmsg(buf, nil, addr, 0)
|
||||
}
|
||||
|
||||
// Send sends a single Message to netlink.
|
||||
func (c *conn) Send(m Message) error {
|
||||
b, err := m.MarshalBinary()
|
||||
|
@ -112,7 +131,10 @@ func (c *conn) Send(m Message) error {
|
|||
func (c *conn) Receive() ([]Message, error) {
|
||||
b := make([]byte, os.Getpagesize())
|
||||
for {
|
||||
// Peek at the buffer to see how many bytes are available
|
||||
// Peek at the buffer to see how many bytes are available.
|
||||
//
|
||||
// TODO(mdlayher): deal with OOB message data if available, such as
|
||||
// when PacketInfo ConnOption is true.
|
||||
n, _, _, _, err := c.s.Recvmsg(b, nil, unix.MSG_PEEK)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
@ -204,6 +226,58 @@ func (c *conn) SetBPF(filter []bpf.RawInstruction) error {
|
|||
)
|
||||
}
|
||||
|
||||
// RemoveBPF removes a BPF filter from a conn.
|
||||
func (c *conn) RemoveBPF() error {
|
||||
// dummy is ignored as argument to SO_DETACH_FILTER
|
||||
// but SetSockopt requires it as an argument
|
||||
var dummy uint32
|
||||
return c.s.SetSockopt(
|
||||
unix.SOL_SOCKET,
|
||||
unix.SO_DETACH_FILTER,
|
||||
unsafe.Pointer(&dummy),
|
||||
uint32(unsafe.Sizeof(dummy)),
|
||||
)
|
||||
}
|
||||
|
||||
// SetOption enables or disables a netlink socket option for the Conn.
|
||||
func (c *conn) SetOption(option ConnOption, enable bool) error {
|
||||
o, ok := linuxOption(option)
|
||||
if !ok {
|
||||
// Return the typical Linux error for an unknown ConnOption.
|
||||
return unix.ENOPROTOOPT
|
||||
}
|
||||
|
||||
var v uint32
|
||||
if enable {
|
||||
v = 1
|
||||
}
|
||||
|
||||
return c.s.SetSockopt(
|
||||
unix.SOL_NETLINK,
|
||||
o,
|
||||
unsafe.Pointer(&v),
|
||||
uint32(unsafe.Sizeof(v)),
|
||||
)
|
||||
}
|
||||
|
||||
// linuxOption converts a ConnOption to its Linux value.
|
||||
func linuxOption(o ConnOption) (int, bool) {
|
||||
switch o {
|
||||
case PacketInfo:
|
||||
return unix.NETLINK_PKTINFO, true
|
||||
case BroadcastError:
|
||||
return unix.NETLINK_BROADCAST_ERROR, true
|
||||
case NoENOBUFS:
|
||||
return unix.NETLINK_NO_ENOBUFS, true
|
||||
case ListenAllNSID:
|
||||
return unix.NETLINK_LISTEN_ALL_NSID, true
|
||||
case CapAcknowledge:
|
||||
return unix.NETLINK_CAP_ACK, true
|
||||
default:
|
||||
return 0, false
|
||||
}
|
||||
}
|
||||
|
||||
// sysToHeader converts a syscall.NlMsghdr to a Header.
|
||||
func sysToHeader(r syscall.NlMsghdr) Header {
|
||||
// NB: the memory layout of Header and syscall.NlMsgHdr must be
|
||||
|
@ -247,10 +321,20 @@ func newSysSocket(lockThread bool) *sysSocket {
|
|||
// But since this is very experimental, we'll leave it as a configurable at
|
||||
// this point.
|
||||
if lockThread {
|
||||
// Never unlock the OS thread, so that the thread will terminate when
|
||||
// the goroutine exits starting in Go 1.10:
|
||||
// The intent is to never unlock the OS thread, so that the thread
|
||||
// will terminate when the goroutine exits starting in Go 1.10:
|
||||
// https://go-review.googlesource.com/c/go/+/46038.
|
||||
//
|
||||
// However, due to recent instability and a potential bad interaction
|
||||
// with the Go runtime for threads which are not unlocked, we have
|
||||
// elected to temporarily unlock the thread:
|
||||
// https://github.com/golang/go/issues/25128#issuecomment-410764489.
|
||||
//
|
||||
// If we ever allow a Conn to set its own network namespace, we must
|
||||
// either ensure that the namespace is restored on exit here or that
|
||||
// the thread is properly terminated at some point in the future.
|
||||
runtime.LockOSThread()
|
||||
defer runtime.UnlockOSThread()
|
||||
}
|
||||
|
||||
defer wg.Done()
|
||||
|
|
49
vendor/github.com/mdlayher/netlink/conn_others.go
generated
vendored
49
vendor/github.com/mdlayher/netlink/conn_others.go
generated
vendored
|
@ -5,14 +5,12 @@ package netlink
|
|||
import (
|
||||
"fmt"
|
||||
"runtime"
|
||||
|
||||
"golang.org/x/net/bpf"
|
||||
)
|
||||
|
||||
var (
|
||||
// errUnimplemented is returned by all functions on platforms that
|
||||
// cannot make use of netlink sockets.
|
||||
errUnimplemented = fmt.Errorf("netlink sockets not implemented on %s/%s",
|
||||
errUnimplemented = fmt.Errorf("netlink: not implemented on %s/%s",
|
||||
runtime.GOOS, runtime.GOARCH)
|
||||
)
|
||||
|
||||
|
@ -21,42 +19,13 @@ var _ Socket = &conn{}
|
|||
// A conn is the no-op implementation of a netlink sockets connection.
|
||||
type conn struct{}
|
||||
|
||||
// dial is the entry point for Dial. dial always returns an error.
|
||||
func dial(family int, config *Config) (*conn, uint32, error) {
|
||||
return nil, 0, errUnimplemented
|
||||
}
|
||||
// All cross-platform functions and Socket methods are unimplemented outside
|
||||
// of Linux.
|
||||
|
||||
// Send always returns an error.
|
||||
func (c *conn) Send(m Message) error {
|
||||
return errUnimplemented
|
||||
}
|
||||
func dial(_ int, _ *Config) (*conn, uint32, error) { return nil, 0, errUnimplemented }
|
||||
func newError(_ int) error { return errUnimplemented }
|
||||
|
||||
// Receive always returns an error.
|
||||
func (c *conn) Receive() ([]Message, error) {
|
||||
return nil, errUnimplemented
|
||||
}
|
||||
|
||||
// Close always returns an error.
|
||||
func (c *conn) Close() error {
|
||||
return errUnimplemented
|
||||
}
|
||||
|
||||
// JoinGroup always returns an error.
|
||||
func (c *conn) JoinGroup(group uint32) error {
|
||||
return errUnimplemented
|
||||
}
|
||||
|
||||
// LeaveGroup always returns an error.
|
||||
func (c *conn) LeaveGroup(group uint32) error {
|
||||
return errUnimplemented
|
||||
}
|
||||
|
||||
// SetBPF always returns an error.
|
||||
func (c *conn) SetBPF(filter []bpf.RawInstruction) error {
|
||||
return errUnimplemented
|
||||
}
|
||||
|
||||
// newError always returns an error.
|
||||
func newError(errno int) error {
|
||||
return errUnimplemented
|
||||
}
|
||||
func (c *conn) Send(_ Message) error { return errUnimplemented }
|
||||
func (c *conn) SendMessages(_ []Message) error { return errUnimplemented }
|
||||
func (c *conn) Receive() ([]Message, error) { return nil, errUnimplemented }
|
||||
func (c *conn) Close() error { return errUnimplemented }
|
||||
|
|
71
vendor/github.com/mdlayher/netlink/debug.go
generated
vendored
Normal file
71
vendor/github.com/mdlayher/netlink/debug.go
generated
vendored
Normal file
|
@ -0,0 +1,71 @@
|
|||
package netlink
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"log"
|
||||
"os"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
var (
|
||||
// Arguments used to create a debugger.
|
||||
debugArgs []string
|
||||
)
|
||||
|
||||
func init() {
|
||||
// Is netlink debugging enabled?
|
||||
s := os.Getenv("NLDEBUG")
|
||||
if s == "" {
|
||||
return
|
||||
}
|
||||
|
||||
debugArgs = strings.Split(s, ",")
|
||||
}
|
||||
|
||||
// A debugger is used to provide debugging information about a netlink connection.
|
||||
type debugger struct {
|
||||
Log *log.Logger
|
||||
Level int
|
||||
}
|
||||
|
||||
// newDebugger creates a debugger by parsing key=value arguments.
|
||||
func newDebugger(args []string) *debugger {
|
||||
d := &debugger{
|
||||
Log: log.New(os.Stderr, "nl: ", 0),
|
||||
Level: 1,
|
||||
}
|
||||
|
||||
for _, a := range args {
|
||||
kv := strings.Split(a, "=")
|
||||
if len(kv) != 2 {
|
||||
// Ignore malformed pairs and assume callers wants defaults.
|
||||
continue
|
||||
}
|
||||
|
||||
switch kv[0] {
|
||||
// Select the log level for the debugger.
|
||||
case "level":
|
||||
level, err := strconv.Atoi(kv[1])
|
||||
if err != nil {
|
||||
panicf("netlink: invalid NLDEBUG level: %q", a)
|
||||
}
|
||||
|
||||
d.Level = level
|
||||
}
|
||||
}
|
||||
|
||||
return d
|
||||
}
|
||||
|
||||
// debugf prints debugging information at the specified level, if d.Level is
|
||||
// high enough to print the message.
|
||||
func (d *debugger) debugf(level int, format string, v ...interface{}) {
|
||||
if d.Level >= level {
|
||||
d.Log.Printf(format, v...)
|
||||
}
|
||||
}
|
||||
|
||||
func panicf(format string, a ...interface{}) {
|
||||
panic(fmt.Sprintf(format, a...))
|
||||
}
|
20
vendor/github.com/mdlayher/netlink/doc.go
generated
vendored
20
vendor/github.com/mdlayher/netlink/doc.go
generated
vendored
|
@ -1,2 +1,22 @@
|
|||
// Package netlink provides low-level access to Linux netlink sockets.
|
||||
//
|
||||
//
|
||||
// Debugging
|
||||
//
|
||||
// This package supports rudimentary netlink connection debugging support.
|
||||
// To enable this, run your binary with the NLDEBUG environment variable set.
|
||||
// Debugging information will be output to stderr with a prefix of "nl:".
|
||||
//
|
||||
// To use the debugging defaults, use:
|
||||
//
|
||||
// $ NLDEBUG=1 ./nlctl
|
||||
//
|
||||
// To configure individual aspects of the debugger, pass key/value options such
|
||||
// as:
|
||||
//
|
||||
// $ NLDEBUG=level=1 ./nlctl
|
||||
//
|
||||
// Available key/value debugger options include:
|
||||
//
|
||||
// level=N: specify the debugging level (only "1" is currently supported)
|
||||
package netlink
|
||||
|
|
16
vendor/github.com/mdlayher/netlink/nlenc/endian.go
generated
vendored
Normal file
16
vendor/github.com/mdlayher/netlink/nlenc/endian.go
generated
vendored
Normal file
|
@ -0,0 +1,16 @@
|
|||
package nlenc
|
||||
|
||||
import (
|
||||
"encoding/binary"
|
||||
)
|
||||
|
||||
// NativeEndian returns the native byte order of this system.
|
||||
func NativeEndian() binary.ByteOrder {
|
||||
// Determine endianness by storing a uint16 in a byte slice.
|
||||
b := Uint16Bytes(1)
|
||||
if b[0] == 1 {
|
||||
return binary.LittleEndian
|
||||
}
|
||||
|
||||
return binary.BigEndian
|
||||
}
|
22
vendor/vendor.json
vendored
22
vendor/vendor.json
vendored
|
@ -85,28 +85,28 @@
|
|||
"versionExact": "v1.0.0"
|
||||
},
|
||||
{
|
||||
"checksumSHA1": "VZIJG8dML/XqZbL9bpeDNgkazcg=",
|
||||
"checksumSHA1": "zLH8BV9kYzpqGB5PS4VDjADFvVM=",
|
||||
"path": "github.com/mdlayher/genetlink",
|
||||
"revision": "76fecce4c787fb8eaa21a8755f722d67c53038e1",
|
||||
"revisionTime": "2017-09-01T18:19:24Z"
|
||||
"revision": "ca85b5a307448462b0aa7a07c67c0846bc12568f",
|
||||
"revisionTime": "2018-07-28T17:03:40Z"
|
||||
},
|
||||
{
|
||||
"checksumSHA1": "S6NatJYh1aOFzSIs6Agp2R0ydtM=",
|
||||
"checksumSHA1": "ybkJbYD6wyjdoPp/KncnDpCyYiU=",
|
||||
"path": "github.com/mdlayher/netlink",
|
||||
"revision": "756e798fb38fac19fb2234d3acc32e902bc1af44",
|
||||
"revisionTime": "2017-12-14T18:12:53Z"
|
||||
"revision": "80a6f93efd374ddee4e0ea862ca0085ef42eed65",
|
||||
"revisionTime": "2018-08-10T15:28:04Z"
|
||||
},
|
||||
{
|
||||
"checksumSHA1": "9nig0WuuiTICStI/8S+pIGqYksc=",
|
||||
"checksumSHA1": "P7eEo2V7/kQEkt2ihW+26S39eEw=",
|
||||
"path": "github.com/mdlayher/netlink/nlenc",
|
||||
"revision": "756e798fb38fac19fb2234d3acc32e902bc1af44",
|
||||
"revisionTime": "2017-12-14T18:12:53Z"
|
||||
"revision": "80a6f93efd374ddee4e0ea862ca0085ef42eed65",
|
||||
"revisionTime": "2018-08-10T15:28:04Z"
|
||||
},
|
||||
{
|
||||
"checksumSHA1": "Y7cjrOeOvA/ic+B8WCp2JyLEuvs=",
|
||||
"path": "github.com/mdlayher/wifi",
|
||||
"revision": "9a2549315201616119128afe421d1601ef3506f9",
|
||||
"revisionTime": "2018-06-15T12:49:15Z"
|
||||
"revision": "efdf3f4195d9fc8b73013b3706fe626b7fb807d8",
|
||||
"revisionTime": "2018-07-27T16:38:19Z"
|
||||
},
|
||||
{
|
||||
"checksumSHA1": "VzutdH69PUqRqhrDVv6F91ebQd4=",
|
||||
|
|
Loading…
Reference in a new issue