8cadff2b79
* CNI: bump to 1.0.1 This commit bumps the declared version of CNI in the Kilo manifests to 1.0.1. This is possible with no changes to the configuration lists because our simple configuration is not affected by any of the deprecations, and there was effectively no change between 0.4.0 and 1.0.0, other than the declaration of a stable API. Similarly, this commit also bumps the version of the CNI library and the plugins package. Bumping to CNI 1.0.0 will help ensure that Kilo stays compatible with container runtimes in the future. Signed-off-by: Lucas Servén Marín <lserven@gmail.com> * vendor: revendor Signed-off-by: Lucas Servén Marín <lserven@gmail.com>
161 lines
4.6 KiB
Go
161 lines
4.6 KiB
Go
package netlink
|
|
|
|
import (
|
|
"fmt"
|
|
"time"
|
|
|
|
"github.com/vishvananda/netlink/nl"
|
|
"github.com/vishvananda/netns"
|
|
"golang.org/x/sys/unix"
|
|
)
|
|
|
|
// Empty handle used by the netlink package methods
|
|
var pkgHandle = &Handle{}
|
|
|
|
// Handle is an handle for the netlink requests on a
|
|
// specific network namespace. All the requests on the
|
|
// same netlink family share the same netlink socket,
|
|
// which gets released when the handle is deleted.
|
|
type Handle struct {
|
|
sockets map[int]*nl.SocketHandle
|
|
lookupByDump bool
|
|
}
|
|
|
|
// SetSocketTimeout configures timeout for default netlink sockets
|
|
func SetSocketTimeout(to time.Duration) error {
|
|
if to < time.Microsecond {
|
|
return fmt.Errorf("invalid timeout, minimul value is %s", time.Microsecond)
|
|
}
|
|
|
|
nl.SocketTimeoutTv = unix.NsecToTimeval(to.Nanoseconds())
|
|
return nil
|
|
}
|
|
|
|
// GetSocketTimeout returns the timeout value used by default netlink sockets
|
|
func GetSocketTimeout() time.Duration {
|
|
nsec := unix.TimevalToNsec(nl.SocketTimeoutTv)
|
|
return time.Duration(nsec) * time.Nanosecond
|
|
}
|
|
|
|
// SupportsNetlinkFamily reports whether the passed netlink family is supported by this Handle
|
|
func (h *Handle) SupportsNetlinkFamily(nlFamily int) bool {
|
|
_, ok := h.sockets[nlFamily]
|
|
return ok
|
|
}
|
|
|
|
// NewHandle returns a netlink handle on the current network namespace.
|
|
// Caller may specify the netlink families the handle should support.
|
|
// If no families are specified, all the families the netlink package
|
|
// supports will be automatically added.
|
|
func NewHandle(nlFamilies ...int) (*Handle, error) {
|
|
return newHandle(netns.None(), netns.None(), nlFamilies...)
|
|
}
|
|
|
|
// SetSocketTimeout sets the send and receive timeout for each socket in the
|
|
// netlink handle. Although the socket timeout has granularity of one
|
|
// microsecond, the effective granularity is floored by the kernel timer tick,
|
|
// which default value is four milliseconds.
|
|
func (h *Handle) SetSocketTimeout(to time.Duration) error {
|
|
if to < time.Microsecond {
|
|
return fmt.Errorf("invalid timeout, minimul value is %s", time.Microsecond)
|
|
}
|
|
tv := unix.NsecToTimeval(to.Nanoseconds())
|
|
for _, sh := range h.sockets {
|
|
if err := sh.Socket.SetSendTimeout(&tv); err != nil {
|
|
return err
|
|
}
|
|
if err := sh.Socket.SetReceiveTimeout(&tv); err != nil {
|
|
return err
|
|
}
|
|
}
|
|
return nil
|
|
}
|
|
|
|
// SetSocketReceiveBufferSize sets the receive buffer size for each
|
|
// socket in the netlink handle. The maximum value is capped by
|
|
// /proc/sys/net/core/rmem_max.
|
|
func (h *Handle) SetSocketReceiveBufferSize(size int, force bool) error {
|
|
opt := unix.SO_RCVBUF
|
|
if force {
|
|
opt = unix.SO_RCVBUFFORCE
|
|
}
|
|
for _, sh := range h.sockets {
|
|
fd := sh.Socket.GetFd()
|
|
err := unix.SetsockoptInt(fd, unix.SOL_SOCKET, opt, size)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
}
|
|
return nil
|
|
}
|
|
|
|
// GetSocketReceiveBufferSize gets the receiver buffer size for each
|
|
// socket in the netlink handle. The retrieved value should be the
|
|
// double to the one set for SetSocketReceiveBufferSize.
|
|
func (h *Handle) GetSocketReceiveBufferSize() ([]int, error) {
|
|
results := make([]int, len(h.sockets))
|
|
i := 0
|
|
for _, sh := range h.sockets {
|
|
fd := sh.Socket.GetFd()
|
|
size, err := unix.GetsockoptInt(fd, unix.SOL_SOCKET, unix.SO_RCVBUF)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
results[i] = size
|
|
i++
|
|
}
|
|
return results, nil
|
|
}
|
|
|
|
// NewHandleAt returns a netlink handle on the network namespace
|
|
// specified by ns. If ns=netns.None(), current network namespace
|
|
// will be assumed
|
|
func NewHandleAt(ns netns.NsHandle, nlFamilies ...int) (*Handle, error) {
|
|
return newHandle(ns, netns.None(), nlFamilies...)
|
|
}
|
|
|
|
// NewHandleAtFrom works as NewHandle but allows client to specify the
|
|
// new and the origin netns Handle.
|
|
func NewHandleAtFrom(newNs, curNs netns.NsHandle) (*Handle, error) {
|
|
return newHandle(newNs, curNs)
|
|
}
|
|
|
|
func newHandle(newNs, curNs netns.NsHandle, nlFamilies ...int) (*Handle, error) {
|
|
h := &Handle{sockets: map[int]*nl.SocketHandle{}}
|
|
fams := nl.SupportedNlFamilies
|
|
if len(nlFamilies) != 0 {
|
|
fams = nlFamilies
|
|
}
|
|
for _, f := range fams {
|
|
s, err := nl.GetNetlinkSocketAt(newNs, curNs, f)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
h.sockets[f] = &nl.SocketHandle{Socket: s}
|
|
}
|
|
return h, nil
|
|
}
|
|
|
|
// Delete releases the resources allocated to this handle
|
|
func (h *Handle) Delete() {
|
|
for _, sh := range h.sockets {
|
|
sh.Close()
|
|
}
|
|
h.sockets = nil
|
|
}
|
|
|
|
func (h *Handle) newNetlinkRequest(proto, flags int) *nl.NetlinkRequest {
|
|
// Do this so that package API still use nl package variable nextSeqNr
|
|
if h.sockets == nil {
|
|
return nl.NewNetlinkRequest(proto, flags)
|
|
}
|
|
return &nl.NetlinkRequest{
|
|
NlMsghdr: unix.NlMsghdr{
|
|
Len: uint32(unix.SizeofNlMsghdr),
|
|
Type: uint16(proto),
|
|
Flags: unix.NLM_F_REQUEST | uint16(flags),
|
|
},
|
|
Sockets: h.sockets,
|
|
}
|
|
}
|