mirror of
https://github.com/rancher/plugins.git
synced 2025-09-14 14:49:19 +00:00
build: update github.com/vishvananda/netlink to 1.3.0
This includes a breaking change:
acdc658b86
route.Dst is now a zero IPNet instead of nil
Signed-off-by: Etienne Champetier <e.champetier@ateme.com>
This commit is contained in:
206
vendor/github.com/vishvananda/netlink/nl/nl_linux.go
generated
vendored
206
vendor/github.com/vishvananda/netlink/nl/nl_linux.go
generated
vendored
@@ -6,6 +6,7 @@ import (
|
||||
"encoding/binary"
|
||||
"fmt"
|
||||
"net"
|
||||
"os"
|
||||
"runtime"
|
||||
"sync"
|
||||
"sync/atomic"
|
||||
@@ -330,6 +331,19 @@ func NewIfInfomsgChild(parent *RtAttr, family int) *IfInfomsg {
|
||||
return msg
|
||||
}
|
||||
|
||||
type Uint32Bitfield struct {
|
||||
Value uint32
|
||||
Selector uint32
|
||||
}
|
||||
|
||||
func (a *Uint32Bitfield) Serialize() []byte {
|
||||
return (*(*[SizeofUint32Bitfield]byte)(unsafe.Pointer(a)))[:]
|
||||
}
|
||||
|
||||
func DeserializeUint32Bitfield(data []byte) *Uint32Bitfield {
|
||||
return (*Uint32Bitfield)(unsafe.Pointer(&data[0:SizeofUint32Bitfield][0]))
|
||||
}
|
||||
|
||||
type Uint32Attribute struct {
|
||||
Type uint16
|
||||
Value uint32
|
||||
@@ -475,10 +489,30 @@ func (req *NetlinkRequest) AddRawData(data []byte) {
|
||||
req.RawData = append(req.RawData, data...)
|
||||
}
|
||||
|
||||
// Execute the request against a the given sockType.
|
||||
// Execute the request against the given sockType.
|
||||
// Returns a list of netlink messages in serialized format, optionally filtered
|
||||
// by resType.
|
||||
func (req *NetlinkRequest) Execute(sockType int, resType uint16) ([][]byte, error) {
|
||||
var res [][]byte
|
||||
err := req.ExecuteIter(sockType, resType, func(msg []byte) bool {
|
||||
res = append(res, msg)
|
||||
return true
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return res, nil
|
||||
}
|
||||
|
||||
// ExecuteIter executes the request against the given sockType.
|
||||
// Calls the provided callback func once for each netlink message.
|
||||
// If the callback returns false, it is not called again, but
|
||||
// the remaining messages are consumed/discarded.
|
||||
//
|
||||
// Thread safety: ExecuteIter holds a lock on the socket until
|
||||
// it finishes iteration so the callback must not call back into
|
||||
// the netlink API.
|
||||
func (req *NetlinkRequest) ExecuteIter(sockType int, resType uint16, f func(msg []byte) bool) error {
|
||||
var (
|
||||
s *NetlinkSocket
|
||||
err error
|
||||
@@ -495,18 +529,18 @@ func (req *NetlinkRequest) Execute(sockType int, resType uint16) ([][]byte, erro
|
||||
if s == nil {
|
||||
s, err = getNetlinkSocket(sockType)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return err
|
||||
}
|
||||
|
||||
if err := s.SetSendTimeout(&SocketTimeoutTv); err != nil {
|
||||
return nil, err
|
||||
return err
|
||||
}
|
||||
if err := s.SetReceiveTimeout(&SocketTimeoutTv); err != nil {
|
||||
return nil, err
|
||||
return err
|
||||
}
|
||||
if EnableErrorMessageReporting {
|
||||
if err := s.SetExtAck(true); err != nil {
|
||||
return nil, err
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
@@ -517,36 +551,44 @@ func (req *NetlinkRequest) Execute(sockType int, resType uint16) ([][]byte, erro
|
||||
}
|
||||
|
||||
if err := s.Send(req); err != nil {
|
||||
return nil, err
|
||||
return err
|
||||
}
|
||||
|
||||
pid, err := s.GetPid()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return err
|
||||
}
|
||||
|
||||
var res [][]byte
|
||||
|
||||
done:
|
||||
for {
|
||||
msgs, from, err := s.Receive()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return err
|
||||
}
|
||||
if from.Pid != PidKernel {
|
||||
return nil, fmt.Errorf("Wrong sender portid %d, expected %d", from.Pid, PidKernel)
|
||||
return fmt.Errorf("Wrong sender portid %d, expected %d", from.Pid, PidKernel)
|
||||
}
|
||||
for _, m := range msgs {
|
||||
if m.Header.Seq != req.Seq {
|
||||
if sharedSocket {
|
||||
continue
|
||||
}
|
||||
return nil, fmt.Errorf("Wrong Seq nr %d, expected %d", m.Header.Seq, req.Seq)
|
||||
return fmt.Errorf("Wrong Seq nr %d, expected %d", m.Header.Seq, req.Seq)
|
||||
}
|
||||
if m.Header.Pid != pid {
|
||||
continue
|
||||
}
|
||||
|
||||
if m.Header.Flags&unix.NLM_F_DUMP_INTR != 0 {
|
||||
return syscall.Errno(unix.EINTR)
|
||||
}
|
||||
|
||||
if m.Header.Type == unix.NLMSG_DONE || m.Header.Type == unix.NLMSG_ERROR {
|
||||
// NLMSG_DONE might have no payload, if so assume no error.
|
||||
if m.Header.Type == unix.NLMSG_DONE && len(m.Data) == 0 {
|
||||
break done
|
||||
}
|
||||
|
||||
native := NativeEndian()
|
||||
errno := int32(native.Uint32(m.Data[0:4]))
|
||||
if errno == 0 {
|
||||
@@ -556,7 +598,7 @@ done:
|
||||
err = syscall.Errno(-errno)
|
||||
|
||||
unreadData := m.Data[4:]
|
||||
if m.Header.Flags|unix.NLM_F_ACK_TLVS != 0 && len(unreadData) > syscall.SizeofNlMsghdr {
|
||||
if m.Header.Flags&unix.NLM_F_ACK_TLVS != 0 && len(unreadData) > syscall.SizeofNlMsghdr {
|
||||
// Skip the echoed request message.
|
||||
echoReqH := (*syscall.NlMsghdr)(unsafe.Pointer(&unreadData[0]))
|
||||
unreadData = unreadData[nlmAlignOf(int(echoReqH.Len)):]
|
||||
@@ -568,8 +610,7 @@ done:
|
||||
|
||||
switch attr.Type {
|
||||
case NLMSGERR_ATTR_MSG:
|
||||
err = fmt.Errorf("%w: %s", err, string(attrData))
|
||||
|
||||
err = fmt.Errorf("%w: %s", err, unix.ByteSliceToString(attrData))
|
||||
default:
|
||||
// TODO: handle other NLMSGERR_ATTR types
|
||||
}
|
||||
@@ -578,18 +619,26 @@ done:
|
||||
}
|
||||
}
|
||||
|
||||
return nil, err
|
||||
return err
|
||||
}
|
||||
if resType != 0 && m.Header.Type != resType {
|
||||
continue
|
||||
}
|
||||
res = append(res, m.Data)
|
||||
if cont := f(m.Data); !cont {
|
||||
// Drain the rest of the messages from the kernel but don't
|
||||
// pass them to the iterator func.
|
||||
f = dummyMsgIterFunc
|
||||
}
|
||||
if m.Header.Flags&unix.NLM_F_MULTI == 0 {
|
||||
break done
|
||||
}
|
||||
}
|
||||
}
|
||||
return res, nil
|
||||
return nil
|
||||
}
|
||||
|
||||
func dummyMsgIterFunc(msg []byte) bool {
|
||||
return true
|
||||
}
|
||||
|
||||
// Create a new netlink request from proto and flags
|
||||
@@ -607,8 +656,9 @@ func NewNetlinkRequest(proto, flags int) *NetlinkRequest {
|
||||
}
|
||||
|
||||
type NetlinkSocket struct {
|
||||
fd int32
|
||||
lsa unix.SockaddrNetlink
|
||||
fd int32
|
||||
file *os.File
|
||||
lsa unix.SockaddrNetlink
|
||||
sync.Mutex
|
||||
}
|
||||
|
||||
@@ -617,8 +667,13 @@ func getNetlinkSocket(protocol int) (*NetlinkSocket, error) {
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
err = unix.SetNonblock(fd, true)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
s := &NetlinkSocket{
|
||||
fd: int32(fd),
|
||||
fd: int32(fd),
|
||||
file: os.NewFile(uintptr(fd), "netlink"),
|
||||
}
|
||||
s.lsa.Family = unix.AF_NETLINK
|
||||
if err := unix.Bind(fd, &s.lsa); err != nil {
|
||||
@@ -649,12 +704,14 @@ func GetNetlinkSocketAt(newNs, curNs netns.NsHandle, protocol int) (*NetlinkSock
|
||||
// In case of success, the caller is expected to execute the returned function
|
||||
// at the end of the code that needs to be executed in the network namespace.
|
||||
// Example:
|
||||
// func jobAt(...) error {
|
||||
// d, err := executeInNetns(...)
|
||||
// if err != nil { return err}
|
||||
// defer d()
|
||||
// < code which needs to be executed in specific netns>
|
||||
// }
|
||||
//
|
||||
// func jobAt(...) error {
|
||||
// d, err := executeInNetns(...)
|
||||
// if err != nil { return err}
|
||||
// defer d()
|
||||
// < code which needs to be executed in specific netns>
|
||||
// }
|
||||
//
|
||||
// TODO: his function probably belongs to netns pkg.
|
||||
func executeInNetns(newNs, curNs netns.NsHandle) (func(), error) {
|
||||
var (
|
||||
@@ -703,8 +760,13 @@ func Subscribe(protocol int, groups ...uint) (*NetlinkSocket, error) {
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
err = unix.SetNonblock(fd, true)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
s := &NetlinkSocket{
|
||||
fd: int32(fd),
|
||||
fd: int32(fd),
|
||||
file: os.NewFile(uintptr(fd), "netlink"),
|
||||
}
|
||||
s.lsa.Family = unix.AF_NETLINK
|
||||
|
||||
@@ -733,33 +795,36 @@ func SubscribeAt(newNs, curNs netns.NsHandle, protocol int, groups ...uint) (*Ne
|
||||
}
|
||||
|
||||
func (s *NetlinkSocket) Close() {
|
||||
fd := int(atomic.SwapInt32(&s.fd, -1))
|
||||
unix.Close(fd)
|
||||
s.file.Close()
|
||||
}
|
||||
|
||||
func (s *NetlinkSocket) GetFd() int {
|
||||
return int(atomic.LoadInt32(&s.fd))
|
||||
return int(s.fd)
|
||||
}
|
||||
|
||||
func (s *NetlinkSocket) Send(request *NetlinkRequest) error {
|
||||
fd := int(atomic.LoadInt32(&s.fd))
|
||||
if fd < 0 {
|
||||
return fmt.Errorf("Send called on a closed socket")
|
||||
}
|
||||
if err := unix.Sendto(fd, request.Serialize(), 0, &s.lsa); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
return unix.Sendto(int(s.fd), request.Serialize(), 0, &s.lsa)
|
||||
}
|
||||
|
||||
func (s *NetlinkSocket) Receive() ([]syscall.NetlinkMessage, *unix.SockaddrNetlink, error) {
|
||||
fd := int(atomic.LoadInt32(&s.fd))
|
||||
if fd < 0 {
|
||||
return nil, nil, fmt.Errorf("Receive called on a closed socket")
|
||||
rawConn, err := s.file.SyscallConn()
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
var (
|
||||
fromAddr *unix.SockaddrNetlink
|
||||
rb [RECEIVE_BUFFER_SIZE]byte
|
||||
nr int
|
||||
from unix.Sockaddr
|
||||
innerErr error
|
||||
)
|
||||
err = rawConn.Read(func(fd uintptr) (done bool) {
|
||||
nr, from, innerErr = unix.Recvfrom(int(fd), rb[:], 0)
|
||||
return innerErr != unix.EWOULDBLOCK
|
||||
})
|
||||
if innerErr != nil {
|
||||
err = innerErr
|
||||
}
|
||||
var fromAddr *unix.SockaddrNetlink
|
||||
var rb [RECEIVE_BUFFER_SIZE]byte
|
||||
nr, from, err := unix.Recvfrom(fd, rb[:], 0)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
@@ -770,8 +835,9 @@ func (s *NetlinkSocket) Receive() ([]syscall.NetlinkMessage, *unix.SockaddrNetli
|
||||
if nr < unix.NLMSG_HDRLEN {
|
||||
return nil, nil, fmt.Errorf("Got short response from netlink")
|
||||
}
|
||||
rb2 := make([]byte, nr)
|
||||
copy(rb2, rb[:nr])
|
||||
msgLen := nlmAlignOf(nr)
|
||||
rb2 := make([]byte, msgLen)
|
||||
copy(rb2, rb[:msgLen])
|
||||
nl, err := syscall.ParseNetlinkMessage(rb2)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
@@ -793,6 +859,15 @@ func (s *NetlinkSocket) SetReceiveTimeout(timeout *unix.Timeval) error {
|
||||
return unix.SetsockoptTimeval(int(s.fd), unix.SOL_SOCKET, unix.SO_RCVTIMEO, timeout)
|
||||
}
|
||||
|
||||
// SetReceiveBufferSize allows to set a receive buffer size on the socket
|
||||
func (s *NetlinkSocket) SetReceiveBufferSize(size int, force bool) error {
|
||||
opt := unix.SO_RCVBUF
|
||||
if force {
|
||||
opt = unix.SO_RCVBUFFORCE
|
||||
}
|
||||
return unix.SetsockoptInt(int(s.fd), unix.SOL_SOCKET, opt, size)
|
||||
}
|
||||
|
||||
// SetExtAck requests error messages to be reported on the socket
|
||||
func (s *NetlinkSocket) SetExtAck(enable bool) error {
|
||||
var enableN int
|
||||
@@ -804,8 +879,7 @@ func (s *NetlinkSocket) SetExtAck(enable bool) error {
|
||||
}
|
||||
|
||||
func (s *NetlinkSocket) GetPid() (uint32, error) {
|
||||
fd := int(atomic.LoadInt32(&s.fd))
|
||||
lsa, err := unix.Getsockname(fd)
|
||||
lsa, err := unix.Getsockname(int(s.fd))
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
@@ -849,6 +923,12 @@ func Uint16Attr(v uint16) []byte {
|
||||
return bytes
|
||||
}
|
||||
|
||||
func BEUint16Attr(v uint16) []byte {
|
||||
bytes := make([]byte, 2)
|
||||
binary.BigEndian.PutUint16(bytes, v)
|
||||
return bytes
|
||||
}
|
||||
|
||||
func Uint32Attr(v uint32) []byte {
|
||||
native := NativeEndian()
|
||||
bytes := make([]byte, 4)
|
||||
@@ -856,6 +936,12 @@ func Uint32Attr(v uint32) []byte {
|
||||
return bytes
|
||||
}
|
||||
|
||||
func BEUint32Attr(v uint32) []byte {
|
||||
bytes := make([]byte, 4)
|
||||
binary.BigEndian.PutUint32(bytes, v)
|
||||
return bytes
|
||||
}
|
||||
|
||||
func Uint64Attr(v uint64) []byte {
|
||||
native := NativeEndian()
|
||||
bytes := make([]byte, 8)
|
||||
@@ -863,6 +949,12 @@ func Uint64Attr(v uint64) []byte {
|
||||
return bytes
|
||||
}
|
||||
|
||||
func BEUint64Attr(v uint64) []byte {
|
||||
bytes := make([]byte, 8)
|
||||
binary.BigEndian.PutUint64(bytes, v)
|
||||
return bytes
|
||||
}
|
||||
|
||||
func ParseRouteAttr(b []byte) ([]syscall.NetlinkRouteAttr, error) {
|
||||
var attrs []syscall.NetlinkRouteAttr
|
||||
for len(b) >= unix.SizeofRtAttr {
|
||||
@@ -877,6 +969,22 @@ func ParseRouteAttr(b []byte) ([]syscall.NetlinkRouteAttr, error) {
|
||||
return attrs, nil
|
||||
}
|
||||
|
||||
// ParseRouteAttrAsMap parses provided buffer that contains raw RtAttrs and returns a map of parsed
|
||||
// atttributes indexed by attribute type or error if occured.
|
||||
func ParseRouteAttrAsMap(b []byte) (map[uint16]syscall.NetlinkRouteAttr, error) {
|
||||
attrMap := make(map[uint16]syscall.NetlinkRouteAttr)
|
||||
|
||||
attrs, err := ParseRouteAttr(b)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
for _, attr := range attrs {
|
||||
attrMap[attr.Attr.Type] = attr
|
||||
}
|
||||
return attrMap, nil
|
||||
}
|
||||
|
||||
func netlinkRouteAttrAndValue(b []byte) (*unix.RtAttr, []byte, int, error) {
|
||||
a := (*unix.RtAttr)(unsafe.Pointer(&b[0]))
|
||||
if int(a.Len) < unix.SizeofRtAttr || int(a.Len) > len(b) {
|
||||
|
Reference in New Issue
Block a user