func (ad *AttributeDecoder) Type() uint16 {
	return ad.a.Type & attrTypeMask
}
Type returns the Attribute.Type field of the current netlink attribute
pointed to by the decoder.

Type masks off the high bits of the netlink attribute type which may contain
the Nested and NetByteOrder flags. These can be obtained by calling TypeFlags.
package netlink
import (
	"encoding/binary"
	"errors"
	"fmt"
	"github.com/josharian/native"
	"github.com/mdlayher/netlink/nlenc"
)
var errInvalidAttribute = errors.New("invalid attribute; length too short or too large")
type Attribute struct {
	Length uint16
	Type uint16
	Data []byte
}
func (a *Attribute) marshal(b []byte) (int, error) {
	if int(a.Length) < nlaHeaderLen {
		return 0, errInvalidAttribute
	}
	nlenc.PutUint16(b[0:2], a.Length)
	nlenc.PutUint16(b[2:4], a.Type)
	n := copy(b[nlaHeaderLen:], a.Data)
	return nlaHeaderLen + nlaAlign(n), nil
}
func (a *Attribute) unmarshal(b []byte) error {
	if len(b) < nlaHeaderLen {
		return errInvalidAttribute
	}
	a.Length = nlenc.Uint16(b[0:2])
	a.Type = nlenc.Uint16(b[2:4])
	if int(a.Length) > len(b) {
		return errInvalidAttribute
	}
	switch {
	case a.Length == 0:
		a.Data = make([]byte, 0)
	case int(a.Length) < nlaHeaderLen:
		return errInvalidAttribute
	case int(a.Length) >= nlaHeaderLen:
		a.Data = make([]byte, len(b[nlaHeaderLen:a.Length]))
		copy(a.Data, b[nlaHeaderLen:a.Length])
	}
	return nil
}
func MarshalAttributes(attrs []Attribute) ([]byte, error) {
	var c int
	for _, a := range attrs {
		c += nlaHeaderLen + nlaAlign(len(a.Data))
	}
	var idx int
	b := make([]byte, c)
	for _, a := range attrs {
		if a.Length == 0 {
			a.Length = uint16(nlaHeaderLen + len(a.Data))
		}
		n, err := a.marshal(b[idx:])
		if err != nil {
			return nil, err
		}
		idx += n
	}
	return b, nil
}
func UnmarshalAttributes(b []byte) ([]Attribute, error) {
	ad, err := NewAttributeDecoder(b)
	if err != nil {
		return nil, err
	}
	if ad.Len() == 0 {
		return nil, nil
	}
	attrs := make([]Attribute, 0, ad.Len())
	for ad.Next() {
		if ad.attr().Length != 0 {
			attrs = append(attrs, ad.attr())
		}
	}
	if err := ad.Err(); err != nil {
		return nil, err
	}
	return attrs, nil
}
type AttributeDecoder struct {
	ByteOrder binary.ByteOrder
	a Attribute
	b []byte
	i int
	length int
	err error
}
func NewAttributeDecoder(b []byte) (*AttributeDecoder, error) {
	ad := &AttributeDecoder{
		ByteOrder: native.Endian,
		b: b,
	}
	var err error
	ad.length, err = ad.available()
	if err != nil {
		return nil, err
	}
	return ad, nil
}
func (ad *AttributeDecoder) Next() bool {
	if ad.err != nil {
		return false
	}
	if ad.i >= len(ad.b) {
		return false
	}
	if err := ad.a.unmarshal(ad.b[ad.i:]); err != nil {
		ad.err = err
		return false
	}
	if int(ad.a.Length) < nlaHeaderLen {
		ad.i += nlaHeaderLen
	} else {
		ad.i += nlaAlign(int(ad.a.Length))
	}
	return true
}