mirror of https://github.com/k3s-io/k3s
Merge pull request #68874 from Lion-Wei/ipvs-graceful-termination-vendor
update vendor for ipvs graceful terminationpull/58/head
commit
ca7b4bab6f
|
@ -1500,8 +1500,7 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "github.com/docker/libnetwork/ipvs",
|
"ImportPath": "github.com/docker/libnetwork/ipvs",
|
||||||
"Comment": "v0.8.0-dev.2-910-gba46b928",
|
"Rev": "a9cd636e37898226332c439363e2ed0ea185ae92"
|
||||||
"Rev": "ba46b928444931e6865d8618dc03622cac79aa6f"
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "github.com/docker/spdystream",
|
"ImportPath": "github.com/docker/spdystream",
|
||||||
|
@ -3062,11 +3061,11 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "github.com/vishvananda/netlink",
|
"ImportPath": "github.com/vishvananda/netlink",
|
||||||
"Rev": "f67b75edbf5e3bb7dfe70bb788610693a71be3d1"
|
"Rev": "b2de5d10e38ecce8607e6b438b6d174f389a004e"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "github.com/vishvananda/netlink/nl",
|
"ImportPath": "github.com/vishvananda/netlink/nl",
|
||||||
"Rev": "f67b75edbf5e3bb7dfe70bb788610693a71be3d1"
|
"Rev": "b2de5d10e38ecce8607e6b438b6d174f389a004e"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "github.com/vishvananda/netns",
|
"ImportPath": "github.com/vishvananda/netns",
|
||||||
|
|
|
@ -5,12 +5,19 @@ package ipvs
|
||||||
import (
|
import (
|
||||||
"net"
|
"net"
|
||||||
"syscall"
|
"syscall"
|
||||||
|
"time"
|
||||||
|
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
"github.com/vishvananda/netlink/nl"
|
"github.com/vishvananda/netlink/nl"
|
||||||
"github.com/vishvananda/netns"
|
"github.com/vishvananda/netns"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
netlinkRecvSocketsTimeout = 3 * time.Second
|
||||||
|
netlinkSendSocketTimeout = 30 * time.Second
|
||||||
|
)
|
||||||
|
|
||||||
// Service defines an IPVS service in its entirety.
|
// Service defines an IPVS service in its entirety.
|
||||||
type Service struct {
|
type Service struct {
|
||||||
// Virtual service address.
|
// Virtual service address.
|
||||||
|
@ -46,13 +53,15 @@ type SvcStats struct {
|
||||||
// Destination defines an IPVS destination (real server) in its
|
// Destination defines an IPVS destination (real server) in its
|
||||||
// entirety.
|
// entirety.
|
||||||
type Destination struct {
|
type Destination struct {
|
||||||
Address net.IP
|
Address net.IP
|
||||||
Port uint16
|
Port uint16
|
||||||
Weight int
|
Weight int
|
||||||
ConnectionFlags uint32
|
ConnectionFlags uint32
|
||||||
AddressFamily uint16
|
AddressFamily uint16
|
||||||
UpperThreshold uint32
|
UpperThreshold uint32
|
||||||
LowerThreshold uint32
|
LowerThreshold uint32
|
||||||
|
ActiveConnections int
|
||||||
|
InactiveConnections int
|
||||||
}
|
}
|
||||||
|
|
||||||
// Handle provides a namespace specific ipvs handle to program ipvs
|
// Handle provides a namespace specific ipvs handle to program ipvs
|
||||||
|
@ -82,6 +91,15 @@ func New(path string) (*Handle, error) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
// Add operation timeout to avoid deadlocks
|
||||||
|
tv := syscall.NsecToTimeval(netlinkSendSocketTimeout.Nanoseconds())
|
||||||
|
if err := sock.SetSendTimeout(&tv); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
tv = syscall.NsecToTimeval(netlinkRecvSocketsTimeout.Nanoseconds())
|
||||||
|
if err := sock.SetReceiveTimeout(&tv); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
return &Handle{sock: sock}, nil
|
return &Handle{sock: sock}, nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -100,7 +100,7 @@ func fillService(s *Service) nl.NetlinkRequestData {
|
||||||
return cmdAttr
|
return cmdAttr
|
||||||
}
|
}
|
||||||
|
|
||||||
func fillDestinaton(d *Destination) nl.NetlinkRequestData {
|
func fillDestination(d *Destination) nl.NetlinkRequestData {
|
||||||
cmdAttr := nl.NewRtAttr(ipvsCmdAttrDest, nil)
|
cmdAttr := nl.NewRtAttr(ipvsCmdAttrDest, nil)
|
||||||
|
|
||||||
nl.NewRtAttrChild(cmdAttr, ipvsDestAttrAddress, rawIPData(d.Address))
|
nl.NewRtAttrChild(cmdAttr, ipvsDestAttrAddress, rawIPData(d.Address))
|
||||||
|
@ -134,7 +134,7 @@ func (i *Handle) doCmdwithResponse(s *Service, d *Destination, cmd uint8) ([][]b
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
req.AddData(fillDestinaton(d))
|
req.AddData(fillDestination(d))
|
||||||
}
|
}
|
||||||
|
|
||||||
res, err := execute(i.sock, req, 0)
|
res, err := execute(i.sock, req, 0)
|
||||||
|
@ -203,10 +203,6 @@ func newGenlRequest(familyID int, cmd uint8) *nl.NetlinkRequest {
|
||||||
}
|
}
|
||||||
|
|
||||||
func execute(s *nl.NetlinkSocket, req *nl.NetlinkRequest, resType uint16) ([][]byte, error) {
|
func execute(s *nl.NetlinkSocket, req *nl.NetlinkRequest, resType uint16) ([][]byte, error) {
|
||||||
var (
|
|
||||||
err error
|
|
||||||
)
|
|
||||||
|
|
||||||
if err := s.Send(req); err != nil {
|
if err := s.Send(req); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -222,6 +218,13 @@ done:
|
||||||
for {
|
for {
|
||||||
msgs, err := s.Receive()
|
msgs, err := s.Receive()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
if s.GetFd() == -1 {
|
||||||
|
return nil, fmt.Errorf("Socket got closed on receive")
|
||||||
|
}
|
||||||
|
if err == syscall.EAGAIN {
|
||||||
|
// timeout fired
|
||||||
|
continue
|
||||||
|
}
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
for _, m := range msgs {
|
for _, m := range msgs {
|
||||||
|
@ -436,6 +439,10 @@ func assembleDestination(attrs []syscall.NetlinkRouteAttr) (*Destination, error)
|
||||||
d.LowerThreshold = native.Uint32(attr.Value)
|
d.LowerThreshold = native.Uint32(attr.Value)
|
||||||
case ipvsDestAttrAddressFamily:
|
case ipvsDestAttrAddressFamily:
|
||||||
d.AddressFamily = native.Uint16(attr.Value)
|
d.AddressFamily = native.Uint16(attr.Value)
|
||||||
|
case ipvsDestAttrActiveConnections:
|
||||||
|
d.ActiveConnections = int(native.Uint16(attr.Value))
|
||||||
|
case ipvsDestAttrInactiveConnections:
|
||||||
|
d.InactiveConnections = int(native.Uint16(attr.Value))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return &d, nil
|
return &d, nil
|
||||||
|
|
|
@ -13,9 +13,6 @@ go_library(
|
||||||
"conntrack_unspecified.go",
|
"conntrack_unspecified.go",
|
||||||
"filter.go",
|
"filter.go",
|
||||||
"filter_linux.go",
|
"filter_linux.go",
|
||||||
"fou.go",
|
|
||||||
"fou_linux.go",
|
|
||||||
"fou_unspecified.go",
|
|
||||||
"genetlink_linux.go",
|
"genetlink_linux.go",
|
||||||
"genetlink_unspecified.go",
|
"genetlink_unspecified.go",
|
||||||
"gtp_linux.go",
|
"gtp_linux.go",
|
||||||
|
@ -54,7 +51,6 @@ go_library(
|
||||||
visibility = ["//visibility:public"],
|
visibility = ["//visibility:public"],
|
||||||
deps = [
|
deps = [
|
||||||
"//vendor/github.com/vishvananda/netlink/nl:go_default_library",
|
"//vendor/github.com/vishvananda/netlink/nl:go_default_library",
|
||||||
"//vendor/golang.org/x/sys/unix:go_default_library",
|
|
||||||
] + select({
|
] + select({
|
||||||
"@io_bazel_rules_go//go/platform:android": [
|
"@io_bazel_rules_go//go/platform:android": [
|
||||||
"//vendor/github.com/vishvananda/netns:go_default_library",
|
"//vendor/github.com/vishvananda/netns:go_default_library",
|
||||||
|
|
|
@ -3,8 +3,7 @@ DIRS := \
|
||||||
nl
|
nl
|
||||||
|
|
||||||
DEPS = \
|
DEPS = \
|
||||||
github.com/vishvananda/netns \
|
github.com/vishvananda/netns
|
||||||
golang.org/x/sys/unix
|
|
||||||
|
|
||||||
uniq = $(if $1,$(firstword $1) $(call uniq,$(filter-out $(firstword $1),$1)))
|
uniq = $(if $1,$(firstword $1) $(call uniq,$(filter-out $(firstword $1),$1)))
|
||||||
testdirs = $(call uniq,$(foreach d,$(1),$(dir $(wildcard $(d)/*_test.go))))
|
testdirs = $(call uniq,$(foreach d,$(1),$(dir $(wildcard $(d)/*_test.go))))
|
||||||
|
@ -19,7 +18,7 @@ $(call goroot,$(DEPS)):
|
||||||
|
|
||||||
.PHONY: $(call testdirs,$(DIRS))
|
.PHONY: $(call testdirs,$(DIRS))
|
||||||
$(call testdirs,$(DIRS)):
|
$(call testdirs,$(DIRS)):
|
||||||
go test -test.exec sudo -test.parallel 4 -timeout 60s -test.v github.com/vishvananda/netlink/$@
|
sudo -E go test -test.parallel 4 -timeout 60s -v github.com/vishvananda/netlink/$@
|
||||||
|
|
||||||
$(call fmt,$(call testdirs,$(DIRS))):
|
$(call fmt,$(call testdirs,$(DIRS))):
|
||||||
! gofmt -l $(subst fmt-,,$@)/*.go | grep -q .
|
! gofmt -l $(subst fmt-,,$@)/*.go | grep -q .
|
||||||
|
|
|
@ -89,4 +89,3 @@ There are also a few pieces of low level netlink functionality that still
|
||||||
need to be implemented. Routing rules are not in place and some of the
|
need to be implemented. Routing rules are not in place and some of the
|
||||||
more advanced link types. Hopefully there is decent structure and testing
|
more advanced link types. Hopefully there is decent structure and testing
|
||||||
in place to make these fairly straightforward to add.
|
in place to make these fairly straightforward to add.
|
||||||
|
|
||||||
|
|
|
@ -4,10 +4,10 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"net"
|
"net"
|
||||||
"strings"
|
"strings"
|
||||||
|
"syscall"
|
||||||
|
|
||||||
"github.com/vishvananda/netlink/nl"
|
"github.com/vishvananda/netlink/nl"
|
||||||
"github.com/vishvananda/netns"
|
"github.com/vishvananda/netns"
|
||||||
"golang.org/x/sys/unix"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// IFA_FLAGS is a u32 attribute.
|
// IFA_FLAGS is a u32 attribute.
|
||||||
|
@ -22,7 +22,7 @@ func AddrAdd(link Link, addr *Addr) error {
|
||||||
// AddrAdd will add an IP address to a link device.
|
// AddrAdd will add an IP address to a link device.
|
||||||
// Equivalent to: `ip addr add $addr dev $link`
|
// Equivalent to: `ip addr add $addr dev $link`
|
||||||
func (h *Handle) AddrAdd(link Link, addr *Addr) error {
|
func (h *Handle) AddrAdd(link Link, addr *Addr) error {
|
||||||
req := h.newNetlinkRequest(unix.RTM_NEWADDR, unix.NLM_F_CREATE|unix.NLM_F_EXCL|unix.NLM_F_ACK)
|
req := h.newNetlinkRequest(syscall.RTM_NEWADDR, syscall.NLM_F_CREATE|syscall.NLM_F_EXCL|syscall.NLM_F_ACK)
|
||||||
return h.addrHandle(link, addr, req)
|
return h.addrHandle(link, addr, req)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -35,7 +35,7 @@ func AddrReplace(link Link, addr *Addr) error {
|
||||||
// AddrReplace will replace (or, if not present, add) an IP address on a link device.
|
// AddrReplace will replace (or, if not present, add) an IP address on a link device.
|
||||||
// Equivalent to: `ip addr replace $addr dev $link`
|
// Equivalent to: `ip addr replace $addr dev $link`
|
||||||
func (h *Handle) AddrReplace(link Link, addr *Addr) error {
|
func (h *Handle) AddrReplace(link Link, addr *Addr) error {
|
||||||
req := h.newNetlinkRequest(unix.RTM_NEWADDR, unix.NLM_F_CREATE|unix.NLM_F_REPLACE|unix.NLM_F_ACK)
|
req := h.newNetlinkRequest(syscall.RTM_NEWADDR, syscall.NLM_F_CREATE|syscall.NLM_F_REPLACE|syscall.NLM_F_ACK)
|
||||||
return h.addrHandle(link, addr, req)
|
return h.addrHandle(link, addr, req)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -48,7 +48,7 @@ func AddrDel(link Link, addr *Addr) error {
|
||||||
// AddrDel will delete an IP address from a link device.
|
// AddrDel will delete an IP address from a link device.
|
||||||
// Equivalent to: `ip addr del $addr dev $link`
|
// Equivalent to: `ip addr del $addr dev $link`
|
||||||
func (h *Handle) AddrDel(link Link, addr *Addr) error {
|
func (h *Handle) AddrDel(link Link, addr *Addr) error {
|
||||||
req := h.newNetlinkRequest(unix.RTM_DELADDR, unix.NLM_F_ACK)
|
req := h.newNetlinkRequest(syscall.RTM_DELADDR, syscall.NLM_F_ACK)
|
||||||
return h.addrHandle(link, addr, req)
|
return h.addrHandle(link, addr, req)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -75,7 +75,7 @@ func (h *Handle) addrHandle(link Link, addr *Addr, req *nl.NetlinkRequest) error
|
||||||
localAddrData = addr.IP.To16()
|
localAddrData = addr.IP.To16()
|
||||||
}
|
}
|
||||||
|
|
||||||
localData := nl.NewRtAttr(unix.IFA_LOCAL, localAddrData)
|
localData := nl.NewRtAttr(syscall.IFA_LOCAL, localAddrData)
|
||||||
req.AddData(localData)
|
req.AddData(localData)
|
||||||
var peerAddrData []byte
|
var peerAddrData []byte
|
||||||
if addr.Peer != nil {
|
if addr.Peer != nil {
|
||||||
|
@ -88,7 +88,7 @@ func (h *Handle) addrHandle(link Link, addr *Addr, req *nl.NetlinkRequest) error
|
||||||
peerAddrData = localAddrData
|
peerAddrData = localAddrData
|
||||||
}
|
}
|
||||||
|
|
||||||
addressData := nl.NewRtAttr(unix.IFA_ADDRESS, peerAddrData)
|
addressData := nl.NewRtAttr(syscall.IFA_ADDRESS, peerAddrData)
|
||||||
req.AddData(addressData)
|
req.AddData(addressData)
|
||||||
|
|
||||||
if addr.Flags != 0 {
|
if addr.Flags != 0 {
|
||||||
|
@ -109,14 +109,14 @@ func (h *Handle) addrHandle(link Link, addr *Addr, req *nl.NetlinkRequest) error
|
||||||
}
|
}
|
||||||
addr.Broadcast = calcBroadcast
|
addr.Broadcast = calcBroadcast
|
||||||
}
|
}
|
||||||
req.AddData(nl.NewRtAttr(unix.IFA_BROADCAST, addr.Broadcast))
|
req.AddData(nl.NewRtAttr(syscall.IFA_BROADCAST, addr.Broadcast))
|
||||||
|
|
||||||
if addr.Label != "" {
|
if addr.Label != "" {
|
||||||
labelData := nl.NewRtAttr(unix.IFA_LABEL, nl.ZeroTerminated(addr.Label))
|
labelData := nl.NewRtAttr(syscall.IFA_LABEL, nl.ZeroTerminated(addr.Label))
|
||||||
req.AddData(labelData)
|
req.AddData(labelData)
|
||||||
}
|
}
|
||||||
|
|
||||||
_, err := req.Execute(unix.NETLINK_ROUTE, 0)
|
_, err := req.Execute(syscall.NETLINK_ROUTE, 0)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -131,11 +131,11 @@ func AddrList(link Link, family int) ([]Addr, error) {
|
||||||
// Equivalent to: `ip addr show`.
|
// Equivalent to: `ip addr show`.
|
||||||
// The list can be filtered by link and ip family.
|
// The list can be filtered by link and ip family.
|
||||||
func (h *Handle) AddrList(link Link, family int) ([]Addr, error) {
|
func (h *Handle) AddrList(link Link, family int) ([]Addr, error) {
|
||||||
req := h.newNetlinkRequest(unix.RTM_GETADDR, unix.NLM_F_DUMP)
|
req := h.newNetlinkRequest(syscall.RTM_GETADDR, syscall.NLM_F_DUMP)
|
||||||
msg := nl.NewIfInfomsg(family)
|
msg := nl.NewIfInfomsg(family)
|
||||||
req.AddData(msg)
|
req.AddData(msg)
|
||||||
|
|
||||||
msgs, err := req.Execute(unix.NETLINK_ROUTE, unix.RTM_NEWADDR)
|
msgs, err := req.Execute(syscall.NETLINK_ROUTE, syscall.RTM_NEWADDR)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -187,21 +187,21 @@ func parseAddr(m []byte) (addr Addr, family, index int, err error) {
|
||||||
var local, dst *net.IPNet
|
var local, dst *net.IPNet
|
||||||
for _, attr := range attrs {
|
for _, attr := range attrs {
|
||||||
switch attr.Attr.Type {
|
switch attr.Attr.Type {
|
||||||
case unix.IFA_ADDRESS:
|
case syscall.IFA_ADDRESS:
|
||||||
dst = &net.IPNet{
|
dst = &net.IPNet{
|
||||||
IP: attr.Value,
|
IP: attr.Value,
|
||||||
Mask: net.CIDRMask(int(msg.Prefixlen), 8*len(attr.Value)),
|
Mask: net.CIDRMask(int(msg.Prefixlen), 8*len(attr.Value)),
|
||||||
}
|
}
|
||||||
addr.Peer = dst
|
addr.Peer = dst
|
||||||
case unix.IFA_LOCAL:
|
case syscall.IFA_LOCAL:
|
||||||
local = &net.IPNet{
|
local = &net.IPNet{
|
||||||
IP: attr.Value,
|
IP: attr.Value,
|
||||||
Mask: net.CIDRMask(int(msg.Prefixlen), 8*len(attr.Value)),
|
Mask: net.CIDRMask(int(msg.Prefixlen), 8*len(attr.Value)),
|
||||||
}
|
}
|
||||||
addr.IPNet = local
|
addr.IPNet = local
|
||||||
case unix.IFA_BROADCAST:
|
case syscall.IFA_BROADCAST:
|
||||||
addr.Broadcast = attr.Value
|
addr.Broadcast = attr.Value
|
||||||
case unix.IFA_LABEL:
|
case syscall.IFA_LABEL:
|
||||||
addr.Label = string(attr.Value[:len(attr.Value)-1])
|
addr.Label = string(attr.Value[:len(attr.Value)-1])
|
||||||
case IFA_FLAGS:
|
case IFA_FLAGS:
|
||||||
addr.Flags = int(native.Uint32(attr.Value[0:4]))
|
addr.Flags = int(native.Uint32(attr.Value[0:4]))
|
||||||
|
@ -264,7 +264,7 @@ func AddrSubscribeWithOptions(ch chan<- AddrUpdate, done <-chan struct{}, option
|
||||||
}
|
}
|
||||||
|
|
||||||
func addrSubscribeAt(newNs, curNs netns.NsHandle, ch chan<- AddrUpdate, done <-chan struct{}, cberr func(error)) error {
|
func addrSubscribeAt(newNs, curNs netns.NsHandle, ch chan<- AddrUpdate, done <-chan struct{}, cberr func(error)) error {
|
||||||
s, err := nl.SubscribeAt(newNs, curNs, unix.NETLINK_ROUTE, unix.RTNLGRP_IPV4_IFADDR, unix.RTNLGRP_IPV6_IFADDR)
|
s, err := nl.SubscribeAt(newNs, curNs, syscall.NETLINK_ROUTE, syscall.RTNLGRP_IPV4_IFADDR, syscall.RTNLGRP_IPV6_IFADDR)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -286,7 +286,7 @@ func addrSubscribeAt(newNs, curNs netns.NsHandle, ch chan<- AddrUpdate, done <-c
|
||||||
}
|
}
|
||||||
for _, m := range msgs {
|
for _, m := range msgs {
|
||||||
msgType := m.Header.Type
|
msgType := m.Header.Type
|
||||||
if msgType != unix.RTM_NEWADDR && msgType != unix.RTM_DELADDR {
|
if msgType != syscall.RTM_NEWADDR && msgType != syscall.RTM_DELADDR {
|
||||||
if cberr != nil {
|
if cberr != nil {
|
||||||
cberr(fmt.Errorf("bad message type: %d", msgType))
|
cberr(fmt.Errorf("bad message type: %d", msgType))
|
||||||
}
|
}
|
||||||
|
@ -303,7 +303,7 @@ func addrSubscribeAt(newNs, curNs netns.NsHandle, ch chan<- AddrUpdate, done <-c
|
||||||
|
|
||||||
ch <- AddrUpdate{LinkAddress: *addr.IPNet,
|
ch <- AddrUpdate{LinkAddress: *addr.IPNet,
|
||||||
LinkIndex: ifindex,
|
LinkIndex: ifindex,
|
||||||
NewAddr: msgType == unix.RTM_NEWADDR,
|
NewAddr: msgType == syscall.RTM_NEWADDR,
|
||||||
Flags: addr.Flags,
|
Flags: addr.Flags,
|
||||||
Scope: addr.Scope,
|
Scope: addr.Scope,
|
||||||
PreferedLft: addr.PreferedLft,
|
PreferedLft: addr.PreferedLft,
|
||||||
|
|
|
@ -2,9 +2,9 @@ package netlink
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"syscall"
|
||||||
|
|
||||||
"github.com/vishvananda/netlink/nl"
|
"github.com/vishvananda/netlink/nl"
|
||||||
"golang.org/x/sys/unix"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// BridgeVlanList gets a map of device id to bridge vlan infos.
|
// BridgeVlanList gets a map of device id to bridge vlan infos.
|
||||||
|
@ -16,12 +16,12 @@ func BridgeVlanList() (map[int32][]*nl.BridgeVlanInfo, error) {
|
||||||
// BridgeVlanList gets a map of device id to bridge vlan infos.
|
// BridgeVlanList gets a map of device id to bridge vlan infos.
|
||||||
// Equivalent to: `bridge vlan show`
|
// Equivalent to: `bridge vlan show`
|
||||||
func (h *Handle) BridgeVlanList() (map[int32][]*nl.BridgeVlanInfo, error) {
|
func (h *Handle) BridgeVlanList() (map[int32][]*nl.BridgeVlanInfo, error) {
|
||||||
req := h.newNetlinkRequest(unix.RTM_GETLINK, unix.NLM_F_DUMP)
|
req := h.newNetlinkRequest(syscall.RTM_GETLINK, syscall.NLM_F_DUMP)
|
||||||
msg := nl.NewIfInfomsg(unix.AF_BRIDGE)
|
msg := nl.NewIfInfomsg(syscall.AF_BRIDGE)
|
||||||
req.AddData(msg)
|
req.AddData(msg)
|
||||||
req.AddData(nl.NewRtAttr(nl.IFLA_EXT_MASK, nl.Uint32Attr(uint32(nl.RTEXT_FILTER_BRVLAN))))
|
req.AddData(nl.NewRtAttr(nl.IFLA_EXT_MASK, nl.Uint32Attr(uint32(nl.RTEXT_FILTER_BRVLAN))))
|
||||||
|
|
||||||
msgs, err := req.Execute(unix.NETLINK_ROUTE, unix.RTM_NEWLINK)
|
msgs, err := req.Execute(syscall.NETLINK_ROUTE, syscall.RTM_NEWLINK)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -63,7 +63,7 @@ func BridgeVlanAdd(link Link, vid uint16, pvid, untagged, self, master bool) err
|
||||||
// BridgeVlanAdd adds a new vlan filter entry
|
// BridgeVlanAdd adds a new vlan filter entry
|
||||||
// Equivalent to: `bridge vlan add dev DEV vid VID [ pvid ] [ untagged ] [ self ] [ master ]`
|
// Equivalent to: `bridge vlan add dev DEV vid VID [ pvid ] [ untagged ] [ self ] [ master ]`
|
||||||
func (h *Handle) BridgeVlanAdd(link Link, vid uint16, pvid, untagged, self, master bool) error {
|
func (h *Handle) BridgeVlanAdd(link Link, vid uint16, pvid, untagged, self, master bool) error {
|
||||||
return h.bridgeVlanModify(unix.RTM_SETLINK, link, vid, pvid, untagged, self, master)
|
return h.bridgeVlanModify(syscall.RTM_SETLINK, link, vid, pvid, untagged, self, master)
|
||||||
}
|
}
|
||||||
|
|
||||||
// BridgeVlanDel adds a new vlan filter entry
|
// BridgeVlanDel adds a new vlan filter entry
|
||||||
|
@ -75,15 +75,15 @@ func BridgeVlanDel(link Link, vid uint16, pvid, untagged, self, master bool) err
|
||||||
// BridgeVlanDel adds a new vlan filter entry
|
// BridgeVlanDel adds a new vlan filter entry
|
||||||
// Equivalent to: `bridge vlan del dev DEV vid VID [ pvid ] [ untagged ] [ self ] [ master ]`
|
// Equivalent to: `bridge vlan del dev DEV vid VID [ pvid ] [ untagged ] [ self ] [ master ]`
|
||||||
func (h *Handle) BridgeVlanDel(link Link, vid uint16, pvid, untagged, self, master bool) error {
|
func (h *Handle) BridgeVlanDel(link Link, vid uint16, pvid, untagged, self, master bool) error {
|
||||||
return h.bridgeVlanModify(unix.RTM_DELLINK, link, vid, pvid, untagged, self, master)
|
return h.bridgeVlanModify(syscall.RTM_DELLINK, link, vid, pvid, untagged, self, master)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *Handle) bridgeVlanModify(cmd int, link Link, vid uint16, pvid, untagged, self, master bool) error {
|
func (h *Handle) bridgeVlanModify(cmd int, link Link, vid uint16, pvid, untagged, self, master bool) error {
|
||||||
base := link.Attrs()
|
base := link.Attrs()
|
||||||
h.ensureIndex(base)
|
h.ensureIndex(base)
|
||||||
req := h.newNetlinkRequest(cmd, unix.NLM_F_ACK)
|
req := h.newNetlinkRequest(cmd, syscall.NLM_F_ACK)
|
||||||
|
|
||||||
msg := nl.NewIfInfomsg(unix.AF_BRIDGE)
|
msg := nl.NewIfInfomsg(syscall.AF_BRIDGE)
|
||||||
msg.Index = int32(base.Index)
|
msg.Index = int32(base.Index)
|
||||||
req.AddData(msg)
|
req.AddData(msg)
|
||||||
|
|
||||||
|
@ -107,7 +107,7 @@ func (h *Handle) bridgeVlanModify(cmd int, link Link, vid uint16, pvid, untagged
|
||||||
}
|
}
|
||||||
nl.NewRtAttrChild(br, nl.IFLA_BRIDGE_VLAN_INFO, vlanInfo.Serialize())
|
nl.NewRtAttrChild(br, nl.IFLA_BRIDGE_VLAN_INFO, vlanInfo.Serialize())
|
||||||
req.AddData(br)
|
req.AddData(br)
|
||||||
_, err := req.Execute(unix.NETLINK_ROUTE, 0)
|
_, err := req.Execute(syscall.NETLINK_ROUTE, 0)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,7 +5,6 @@ import (
|
||||||
"syscall"
|
"syscall"
|
||||||
|
|
||||||
"github.com/vishvananda/netlink/nl"
|
"github.com/vishvananda/netlink/nl"
|
||||||
"golang.org/x/sys/unix"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// NOTE: function is in here because it uses other linux functions
|
// NOTE: function is in here because it uses other linux functions
|
||||||
|
@ -51,7 +50,7 @@ func ClassDel(class Class) error {
|
||||||
// ClassDel will delete a class from the system.
|
// ClassDel will delete a class from the system.
|
||||||
// Equivalent to: `tc class del $class`
|
// Equivalent to: `tc class del $class`
|
||||||
func (h *Handle) ClassDel(class Class) error {
|
func (h *Handle) ClassDel(class Class) error {
|
||||||
return h.classModify(unix.RTM_DELTCLASS, 0, class)
|
return h.classModify(syscall.RTM_DELTCLASS, 0, class)
|
||||||
}
|
}
|
||||||
|
|
||||||
// ClassChange will change a class in place
|
// ClassChange will change a class in place
|
||||||
|
@ -65,7 +64,7 @@ func ClassChange(class Class) error {
|
||||||
// Equivalent to: `tc class change $class`
|
// Equivalent to: `tc class change $class`
|
||||||
// The parent and handle MUST NOT be changed.
|
// The parent and handle MUST NOT be changed.
|
||||||
func (h *Handle) ClassChange(class Class) error {
|
func (h *Handle) ClassChange(class Class) error {
|
||||||
return h.classModify(unix.RTM_NEWTCLASS, 0, class)
|
return h.classModify(syscall.RTM_NEWTCLASS, 0, class)
|
||||||
}
|
}
|
||||||
|
|
||||||
// ClassReplace will replace a class to the system.
|
// ClassReplace will replace a class to the system.
|
||||||
|
@ -83,7 +82,7 @@ func ClassReplace(class Class) error {
|
||||||
// If a class already exist with this parent/handle pair, the class is changed.
|
// If a class already exist with this parent/handle pair, the class is changed.
|
||||||
// If a class does not already exist with this parent/handle, a new class is created.
|
// If a class does not already exist with this parent/handle, a new class is created.
|
||||||
func (h *Handle) ClassReplace(class Class) error {
|
func (h *Handle) ClassReplace(class Class) error {
|
||||||
return h.classModify(unix.RTM_NEWTCLASS, unix.NLM_F_CREATE, class)
|
return h.classModify(syscall.RTM_NEWTCLASS, syscall.NLM_F_CREATE, class)
|
||||||
}
|
}
|
||||||
|
|
||||||
// ClassAdd will add a class to the system.
|
// ClassAdd will add a class to the system.
|
||||||
|
@ -96,14 +95,14 @@ func ClassAdd(class Class) error {
|
||||||
// Equivalent to: `tc class add $class`
|
// Equivalent to: `tc class add $class`
|
||||||
func (h *Handle) ClassAdd(class Class) error {
|
func (h *Handle) ClassAdd(class Class) error {
|
||||||
return h.classModify(
|
return h.classModify(
|
||||||
unix.RTM_NEWTCLASS,
|
syscall.RTM_NEWTCLASS,
|
||||||
unix.NLM_F_CREATE|unix.NLM_F_EXCL,
|
syscall.NLM_F_CREATE|syscall.NLM_F_EXCL,
|
||||||
class,
|
class,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *Handle) classModify(cmd, flags int, class Class) error {
|
func (h *Handle) classModify(cmd, flags int, class Class) error {
|
||||||
req := h.newNetlinkRequest(cmd, flags|unix.NLM_F_ACK)
|
req := h.newNetlinkRequest(cmd, flags|syscall.NLM_F_ACK)
|
||||||
base := class.Attrs()
|
base := class.Attrs()
|
||||||
msg := &nl.TcMsg{
|
msg := &nl.TcMsg{
|
||||||
Family: nl.FAMILY_ALL,
|
Family: nl.FAMILY_ALL,
|
||||||
|
@ -113,12 +112,12 @@ func (h *Handle) classModify(cmd, flags int, class Class) error {
|
||||||
}
|
}
|
||||||
req.AddData(msg)
|
req.AddData(msg)
|
||||||
|
|
||||||
if cmd != unix.RTM_DELTCLASS {
|
if cmd != syscall.RTM_DELTCLASS {
|
||||||
if err := classPayload(req, class); err != nil {
|
if err := classPayload(req, class); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_, err := req.Execute(unix.NETLINK_ROUTE, 0)
|
_, err := req.Execute(syscall.NETLINK_ROUTE, 0)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -142,12 +141,12 @@ func classPayload(req *nl.NetlinkRequest, class Class) error {
|
||||||
var rtab [256]uint32
|
var rtab [256]uint32
|
||||||
var ctab [256]uint32
|
var ctab [256]uint32
|
||||||
tcrate := nl.TcRateSpec{Rate: uint32(htb.Rate)}
|
tcrate := nl.TcRateSpec{Rate: uint32(htb.Rate)}
|
||||||
if CalcRtable(&tcrate, rtab[:], cellLog, uint32(mtu), linklayer) < 0 {
|
if CalcRtable(&tcrate, rtab, cellLog, uint32(mtu), linklayer) < 0 {
|
||||||
return errors.New("HTB: failed to calculate rate table")
|
return errors.New("HTB: failed to calculate rate table")
|
||||||
}
|
}
|
||||||
opt.Rate = tcrate
|
opt.Rate = tcrate
|
||||||
tcceil := nl.TcRateSpec{Rate: uint32(htb.Ceil)}
|
tcceil := nl.TcRateSpec{Rate: uint32(htb.Ceil)}
|
||||||
if CalcRtable(&tcceil, ctab[:], ccellLog, uint32(mtu), linklayer) < 0 {
|
if CalcRtable(&tcceil, ctab, ccellLog, uint32(mtu), linklayer) < 0 {
|
||||||
return errors.New("HTB: failed to calculate ceil rate table")
|
return errors.New("HTB: failed to calculate ceil rate table")
|
||||||
}
|
}
|
||||||
opt.Ceil = tcceil
|
opt.Ceil = tcceil
|
||||||
|
@ -170,7 +169,7 @@ func ClassList(link Link, parent uint32) ([]Class, error) {
|
||||||
// Equivalent to: `tc class show`.
|
// Equivalent to: `tc class show`.
|
||||||
// Generally returns nothing if link and parent are not specified.
|
// Generally returns nothing if link and parent are not specified.
|
||||||
func (h *Handle) ClassList(link Link, parent uint32) ([]Class, error) {
|
func (h *Handle) ClassList(link Link, parent uint32) ([]Class, error) {
|
||||||
req := h.newNetlinkRequest(unix.RTM_GETTCLASS, unix.NLM_F_DUMP)
|
req := h.newNetlinkRequest(syscall.RTM_GETTCLASS, syscall.NLM_F_DUMP)
|
||||||
msg := &nl.TcMsg{
|
msg := &nl.TcMsg{
|
||||||
Family: nl.FAMILY_ALL,
|
Family: nl.FAMILY_ALL,
|
||||||
Parent: parent,
|
Parent: parent,
|
||||||
|
@ -182,7 +181,7 @@ func (h *Handle) ClassList(link Link, parent uint32) ([]Class, error) {
|
||||||
}
|
}
|
||||||
req.AddData(msg)
|
req.AddData(msg)
|
||||||
|
|
||||||
msgs, err := req.Execute(unix.NETLINK_ROUTE, unix.RTM_NEWTCLASS)
|
msgs, err := req.Execute(syscall.NETLINK_ROUTE, syscall.RTM_NEWTCLASS)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,9 +6,9 @@ import (
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"net"
|
"net"
|
||||||
|
"syscall"
|
||||||
|
|
||||||
"github.com/vishvananda/netlink/nl"
|
"github.com/vishvananda/netlink/nl"
|
||||||
"golang.org/x/sys/unix"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// ConntrackTableType Conntrack table for the netlink operation
|
// ConntrackTableType Conntrack table for the netlink operation
|
||||||
|
@ -85,8 +85,8 @@ func (h *Handle) ConntrackTableList(table ConntrackTableType, family InetFamily)
|
||||||
// conntrack -F [table] Flush table
|
// conntrack -F [table] Flush table
|
||||||
// The flush operation applies to all the family types
|
// The flush operation applies to all the family types
|
||||||
func (h *Handle) ConntrackTableFlush(table ConntrackTableType) error {
|
func (h *Handle) ConntrackTableFlush(table ConntrackTableType) error {
|
||||||
req := h.newConntrackRequest(table, unix.AF_INET, nl.IPCTNL_MSG_CT_DELETE, unix.NLM_F_ACK)
|
req := h.newConntrackRequest(table, syscall.AF_INET, nl.IPCTNL_MSG_CT_DELETE, syscall.NLM_F_ACK)
|
||||||
_, err := req.Execute(unix.NETLINK_NETFILTER, 0)
|
_, err := req.Execute(syscall.NETLINK_NETFILTER, 0)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -102,10 +102,10 @@ func (h *Handle) ConntrackDeleteFilter(table ConntrackTableType, family InetFami
|
||||||
for _, dataRaw := range res {
|
for _, dataRaw := range res {
|
||||||
flow := parseRawData(dataRaw)
|
flow := parseRawData(dataRaw)
|
||||||
if match := filter.MatchConntrackFlow(flow); match {
|
if match := filter.MatchConntrackFlow(flow); match {
|
||||||
req2 := h.newConntrackRequest(table, family, nl.IPCTNL_MSG_CT_DELETE, unix.NLM_F_ACK)
|
req2 := h.newConntrackRequest(table, family, nl.IPCTNL_MSG_CT_DELETE, syscall.NLM_F_ACK)
|
||||||
// skip the first 4 byte that are the netfilter header, the newConntrackRequest is adding it already
|
// skip the first 4 byte that are the netfilter header, the newConntrackRequest is adding it already
|
||||||
req2.AddRawData(dataRaw[4:])
|
req2.AddRawData(dataRaw[4:])
|
||||||
req2.Execute(unix.NETLINK_NETFILTER, 0)
|
req2.Execute(syscall.NETLINK_NETFILTER, 0)
|
||||||
matched++
|
matched++
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -127,8 +127,8 @@ func (h *Handle) newConntrackRequest(table ConntrackTableType, family InetFamily
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *Handle) dumpConntrackTable(table ConntrackTableType, family InetFamily) ([][]byte, error) {
|
func (h *Handle) dumpConntrackTable(table ConntrackTableType, family InetFamily) ([][]byte, error) {
|
||||||
req := h.newConntrackRequest(table, family, nl.IPCTNL_MSG_CT_GET, unix.NLM_F_DUMP)
|
req := h.newConntrackRequest(table, family, nl.IPCTNL_MSG_CT_GET, syscall.NLM_F_DUMP)
|
||||||
return req.Execute(unix.NETLINK_NETFILTER, 0)
|
return req.Execute(syscall.NETLINK_NETFILTER, 0)
|
||||||
}
|
}
|
||||||
|
|
||||||
// The full conntrack flow structure is very complicated and can be found in the file:
|
// The full conntrack flow structure is very complicated and can be found in the file:
|
||||||
|
|
|
@ -17,7 +17,7 @@ type FilterAttrs struct {
|
||||||
Handle uint32
|
Handle uint32
|
||||||
Parent uint32
|
Parent uint32
|
||||||
Priority uint16 // lower is higher priority
|
Priority uint16 // lower is higher priority
|
||||||
Protocol uint16 // unix.ETH_P_*
|
Protocol uint16 // syscall.ETH_P_*
|
||||||
}
|
}
|
||||||
|
|
||||||
func (q FilterAttrs) String() string {
|
func (q FilterAttrs) String() string {
|
||||||
|
|
|
@ -9,7 +9,6 @@ import (
|
||||||
"unsafe"
|
"unsafe"
|
||||||
|
|
||||||
"github.com/vishvananda/netlink/nl"
|
"github.com/vishvananda/netlink/nl"
|
||||||
"golang.org/x/sys/unix"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// Constants used in TcU32Sel.Flags.
|
// Constants used in TcU32Sel.Flags.
|
||||||
|
@ -56,7 +55,7 @@ func NewFw(attrs FilterAttrs, fattrs FilterFwAttrs) (*Fw, error) {
|
||||||
if police.Rate.Rate != 0 {
|
if police.Rate.Rate != 0 {
|
||||||
police.Rate.Mpu = fattrs.Mpu
|
police.Rate.Mpu = fattrs.Mpu
|
||||||
police.Rate.Overhead = fattrs.Overhead
|
police.Rate.Overhead = fattrs.Overhead
|
||||||
if CalcRtable(&police.Rate, rtab[:], rcellLog, fattrs.Mtu, linklayer) < 0 {
|
if CalcRtable(&police.Rate, rtab, rcellLog, fattrs.Mtu, linklayer) < 0 {
|
||||||
return nil, errors.New("TBF: failed to calculate rate table")
|
return nil, errors.New("TBF: failed to calculate rate table")
|
||||||
}
|
}
|
||||||
police.Burst = uint32(Xmittime(uint64(police.Rate.Rate), uint32(buffer)))
|
police.Burst = uint32(Xmittime(uint64(police.Rate.Rate), uint32(buffer)))
|
||||||
|
@ -65,7 +64,7 @@ func NewFw(attrs FilterAttrs, fattrs FilterFwAttrs) (*Fw, error) {
|
||||||
if police.PeakRate.Rate != 0 {
|
if police.PeakRate.Rate != 0 {
|
||||||
police.PeakRate.Mpu = fattrs.Mpu
|
police.PeakRate.Mpu = fattrs.Mpu
|
||||||
police.PeakRate.Overhead = fattrs.Overhead
|
police.PeakRate.Overhead = fattrs.Overhead
|
||||||
if CalcRtable(&police.PeakRate, ptab[:], pcellLog, fattrs.Mtu, linklayer) < 0 {
|
if CalcRtable(&police.PeakRate, ptab, pcellLog, fattrs.Mtu, linklayer) < 0 {
|
||||||
return nil, errors.New("POLICE: failed to calculate peak rate table")
|
return nil, errors.New("POLICE: failed to calculate peak rate table")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -99,7 +98,7 @@ func FilterDel(filter Filter) error {
|
||||||
// FilterDel will delete a filter from the system.
|
// FilterDel will delete a filter from the system.
|
||||||
// Equivalent to: `tc filter del $filter`
|
// Equivalent to: `tc filter del $filter`
|
||||||
func (h *Handle) FilterDel(filter Filter) error {
|
func (h *Handle) FilterDel(filter Filter) error {
|
||||||
req := h.newNetlinkRequest(unix.RTM_DELTFILTER, unix.NLM_F_ACK)
|
req := h.newNetlinkRequest(syscall.RTM_DELTFILTER, syscall.NLM_F_ACK)
|
||||||
base := filter.Attrs()
|
base := filter.Attrs()
|
||||||
msg := &nl.TcMsg{
|
msg := &nl.TcMsg{
|
||||||
Family: nl.FAMILY_ALL,
|
Family: nl.FAMILY_ALL,
|
||||||
|
@ -110,7 +109,7 @@ func (h *Handle) FilterDel(filter Filter) error {
|
||||||
}
|
}
|
||||||
req.AddData(msg)
|
req.AddData(msg)
|
||||||
|
|
||||||
_, err := req.Execute(unix.NETLINK_ROUTE, 0)
|
_, err := req.Execute(syscall.NETLINK_ROUTE, 0)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -124,7 +123,7 @@ func FilterAdd(filter Filter) error {
|
||||||
// Equivalent to: `tc filter add $filter`
|
// Equivalent to: `tc filter add $filter`
|
||||||
func (h *Handle) FilterAdd(filter Filter) error {
|
func (h *Handle) FilterAdd(filter Filter) error {
|
||||||
native = nl.NativeEndian()
|
native = nl.NativeEndian()
|
||||||
req := h.newNetlinkRequest(unix.RTM_NEWTFILTER, unix.NLM_F_CREATE|unix.NLM_F_EXCL|unix.NLM_F_ACK)
|
req := h.newNetlinkRequest(syscall.RTM_NEWTFILTER, syscall.NLM_F_CREATE|syscall.NLM_F_EXCL|syscall.NLM_F_ACK)
|
||||||
base := filter.Attrs()
|
base := filter.Attrs()
|
||||||
msg := &nl.TcMsg{
|
msg := &nl.TcMsg{
|
||||||
Family: nl.FAMILY_ALL,
|
Family: nl.FAMILY_ALL,
|
||||||
|
@ -225,7 +224,7 @@ func (h *Handle) FilterAdd(filter Filter) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
req.AddData(options)
|
req.AddData(options)
|
||||||
_, err := req.Execute(unix.NETLINK_ROUTE, 0)
|
_, err := req.Execute(syscall.NETLINK_ROUTE, 0)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -240,7 +239,7 @@ func FilterList(link Link, parent uint32) ([]Filter, error) {
|
||||||
// Equivalent to: `tc filter show`.
|
// Equivalent to: `tc filter show`.
|
||||||
// Generally returns nothing if link and parent are not specified.
|
// Generally returns nothing if link and parent are not specified.
|
||||||
func (h *Handle) FilterList(link Link, parent uint32) ([]Filter, error) {
|
func (h *Handle) FilterList(link Link, parent uint32) ([]Filter, error) {
|
||||||
req := h.newNetlinkRequest(unix.RTM_GETTFILTER, unix.NLM_F_DUMP)
|
req := h.newNetlinkRequest(syscall.RTM_GETTFILTER, syscall.NLM_F_DUMP)
|
||||||
msg := &nl.TcMsg{
|
msg := &nl.TcMsg{
|
||||||
Family: nl.FAMILY_ALL,
|
Family: nl.FAMILY_ALL,
|
||||||
Parent: parent,
|
Parent: parent,
|
||||||
|
@ -252,7 +251,7 @@ func (h *Handle) FilterList(link Link, parent uint32) ([]Filter, error) {
|
||||||
}
|
}
|
||||||
req.AddData(msg)
|
req.AddData(msg)
|
||||||
|
|
||||||
msgs, err := req.Execute(unix.NETLINK_ROUTE, unix.RTM_NEWTFILTER)
|
msgs, err := req.Execute(syscall.NETLINK_ROUTE, syscall.RTM_NEWTFILTER)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -563,7 +562,7 @@ func AdjustSize(sz uint, mpu uint, linklayer int) uint {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func CalcRtable(rate *nl.TcRateSpec, rtab []uint32, cellLog int, mtu uint32, linklayer int) int {
|
func CalcRtable(rate *nl.TcRateSpec, rtab [256]uint32, cellLog int, mtu uint32, linklayer int) int {
|
||||||
bps := rate.Rate
|
bps := rate.Rate
|
||||||
mpu := rate.Mpu
|
mpu := rate.Mpu
|
||||||
var sz uint
|
var sz uint
|
||||||
|
|
|
@ -1,21 +0,0 @@
|
||||||
package netlink
|
|
||||||
|
|
||||||
import (
|
|
||||||
"errors"
|
|
||||||
)
|
|
||||||
|
|
||||||
var (
|
|
||||||
// ErrAttrHeaderTruncated is returned when a netlink attribute's header is
|
|
||||||
// truncated.
|
|
||||||
ErrAttrHeaderTruncated = errors.New("attribute header truncated")
|
|
||||||
// ErrAttrBodyTruncated is returned when a netlink attribute's body is
|
|
||||||
// truncated.
|
|
||||||
ErrAttrBodyTruncated = errors.New("attribute body truncated")
|
|
||||||
)
|
|
||||||
|
|
||||||
type Fou struct {
|
|
||||||
Family int
|
|
||||||
Port int
|
|
||||||
Protocol int
|
|
||||||
EncapType int
|
|
||||||
}
|
|
|
@ -1,215 +0,0 @@
|
||||||
// +build linux
|
|
||||||
|
|
||||||
package netlink
|
|
||||||
|
|
||||||
import (
|
|
||||||
"encoding/binary"
|
|
||||||
"errors"
|
|
||||||
|
|
||||||
"github.com/vishvananda/netlink/nl"
|
|
||||||
"golang.org/x/sys/unix"
|
|
||||||
)
|
|
||||||
|
|
||||||
const (
|
|
||||||
FOU_GENL_NAME = "fou"
|
|
||||||
)
|
|
||||||
|
|
||||||
const (
|
|
||||||
FOU_CMD_UNSPEC uint8 = iota
|
|
||||||
FOU_CMD_ADD
|
|
||||||
FOU_CMD_DEL
|
|
||||||
FOU_CMD_GET
|
|
||||||
FOU_CMD_MAX = FOU_CMD_GET
|
|
||||||
)
|
|
||||||
|
|
||||||
const (
|
|
||||||
FOU_ATTR_UNSPEC = iota
|
|
||||||
FOU_ATTR_PORT
|
|
||||||
FOU_ATTR_AF
|
|
||||||
FOU_ATTR_IPPROTO
|
|
||||||
FOU_ATTR_TYPE
|
|
||||||
FOU_ATTR_REMCSUM_NOPARTIAL
|
|
||||||
FOU_ATTR_MAX = FOU_ATTR_REMCSUM_NOPARTIAL
|
|
||||||
)
|
|
||||||
|
|
||||||
const (
|
|
||||||
FOU_ENCAP_UNSPEC = iota
|
|
||||||
FOU_ENCAP_DIRECT
|
|
||||||
FOU_ENCAP_GUE
|
|
||||||
FOU_ENCAP_MAX = FOU_ENCAP_GUE
|
|
||||||
)
|
|
||||||
|
|
||||||
var fouFamilyId int
|
|
||||||
|
|
||||||
func FouFamilyId() (int, error) {
|
|
||||||
if fouFamilyId != 0 {
|
|
||||||
return fouFamilyId, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
fam, err := GenlFamilyGet(FOU_GENL_NAME)
|
|
||||||
if err != nil {
|
|
||||||
return -1, err
|
|
||||||
}
|
|
||||||
|
|
||||||
fouFamilyId = int(fam.ID)
|
|
||||||
return fouFamilyId, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func FouAdd(f Fou) error {
|
|
||||||
return pkgHandle.FouAdd(f)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (h *Handle) FouAdd(f Fou) error {
|
|
||||||
fam_id, err := FouFamilyId()
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
// setting ip protocol conflicts with encapsulation type GUE
|
|
||||||
if f.EncapType == FOU_ENCAP_GUE && f.Protocol != 0 {
|
|
||||||
return errors.New("GUE encapsulation doesn't specify an IP protocol")
|
|
||||||
}
|
|
||||||
|
|
||||||
req := h.newNetlinkRequest(fam_id, unix.NLM_F_ACK)
|
|
||||||
|
|
||||||
// int to byte for port
|
|
||||||
bp := make([]byte, 2)
|
|
||||||
binary.BigEndian.PutUint16(bp[0:2], uint16(f.Port))
|
|
||||||
|
|
||||||
attrs := []*nl.RtAttr{
|
|
||||||
nl.NewRtAttr(FOU_ATTR_PORT, bp),
|
|
||||||
nl.NewRtAttr(FOU_ATTR_TYPE, []byte{uint8(f.EncapType)}),
|
|
||||||
nl.NewRtAttr(FOU_ATTR_AF, []byte{uint8(f.Family)}),
|
|
||||||
nl.NewRtAttr(FOU_ATTR_IPPROTO, []byte{uint8(f.Protocol)}),
|
|
||||||
}
|
|
||||||
raw := []byte{FOU_CMD_ADD, 1, 0, 0}
|
|
||||||
for _, a := range attrs {
|
|
||||||
raw = append(raw, a.Serialize()...)
|
|
||||||
}
|
|
||||||
|
|
||||||
req.AddRawData(raw)
|
|
||||||
|
|
||||||
_, err = req.Execute(unix.NETLINK_GENERIC, 0)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func FouDel(f Fou) error {
|
|
||||||
return pkgHandle.FouDel(f)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (h *Handle) FouDel(f Fou) error {
|
|
||||||
fam_id, err := FouFamilyId()
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
req := h.newNetlinkRequest(fam_id, unix.NLM_F_ACK)
|
|
||||||
|
|
||||||
// int to byte for port
|
|
||||||
bp := make([]byte, 2)
|
|
||||||
binary.BigEndian.PutUint16(bp[0:2], uint16(f.Port))
|
|
||||||
|
|
||||||
attrs := []*nl.RtAttr{
|
|
||||||
nl.NewRtAttr(FOU_ATTR_PORT, bp),
|
|
||||||
nl.NewRtAttr(FOU_ATTR_AF, []byte{uint8(f.Family)}),
|
|
||||||
}
|
|
||||||
raw := []byte{FOU_CMD_DEL, 1, 0, 0}
|
|
||||||
for _, a := range attrs {
|
|
||||||
raw = append(raw, a.Serialize()...)
|
|
||||||
}
|
|
||||||
|
|
||||||
req.AddRawData(raw)
|
|
||||||
|
|
||||||
_, err = req.Execute(unix.NETLINK_GENERIC, 0)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func FouList(fam int) ([]Fou, error) {
|
|
||||||
return pkgHandle.FouList(fam)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (h *Handle) FouList(fam int) ([]Fou, error) {
|
|
||||||
fam_id, err := FouFamilyId()
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
req := h.newNetlinkRequest(fam_id, unix.NLM_F_DUMP)
|
|
||||||
|
|
||||||
attrs := []*nl.RtAttr{
|
|
||||||
nl.NewRtAttr(FOU_ATTR_AF, []byte{uint8(fam)}),
|
|
||||||
}
|
|
||||||
raw := []byte{FOU_CMD_GET, 1, 0, 0}
|
|
||||||
for _, a := range attrs {
|
|
||||||
raw = append(raw, a.Serialize()...)
|
|
||||||
}
|
|
||||||
|
|
||||||
req.AddRawData(raw)
|
|
||||||
|
|
||||||
msgs, err := req.Execute(unix.NETLINK_GENERIC, 0)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
fous := make([]Fou, 0, len(msgs))
|
|
||||||
for _, m := range msgs {
|
|
||||||
f, err := deserializeFouMsg(m)
|
|
||||||
if err != nil {
|
|
||||||
return fous, err
|
|
||||||
}
|
|
||||||
|
|
||||||
fous = append(fous, f)
|
|
||||||
}
|
|
||||||
|
|
||||||
return fous, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func deserializeFouMsg(msg []byte) (Fou, error) {
|
|
||||||
// we'll skip to byte 4 to first attribute
|
|
||||||
msg = msg[3:]
|
|
||||||
var shift int
|
|
||||||
fou := Fou{}
|
|
||||||
|
|
||||||
for {
|
|
||||||
// attribute header is at least 16 bits
|
|
||||||
if len(msg) < 4 {
|
|
||||||
return fou, ErrAttrHeaderTruncated
|
|
||||||
}
|
|
||||||
|
|
||||||
lgt := int(binary.BigEndian.Uint16(msg[0:2]))
|
|
||||||
if len(msg) < lgt+4 {
|
|
||||||
return fou, ErrAttrBodyTruncated
|
|
||||||
}
|
|
||||||
attr := binary.BigEndian.Uint16(msg[2:4])
|
|
||||||
|
|
||||||
shift = lgt + 3
|
|
||||||
switch attr {
|
|
||||||
case FOU_ATTR_AF:
|
|
||||||
fou.Family = int(msg[5])
|
|
||||||
case FOU_ATTR_PORT:
|
|
||||||
fou.Port = int(binary.BigEndian.Uint16(msg[5:7]))
|
|
||||||
// port is 2 bytes
|
|
||||||
shift = lgt + 2
|
|
||||||
case FOU_ATTR_IPPROTO:
|
|
||||||
fou.Protocol = int(msg[5])
|
|
||||||
case FOU_ATTR_TYPE:
|
|
||||||
fou.EncapType = int(msg[5])
|
|
||||||
}
|
|
||||||
|
|
||||||
msg = msg[shift:]
|
|
||||||
|
|
||||||
if len(msg) < 4 {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return fou, nil
|
|
||||||
}
|
|
|
@ -1,15 +0,0 @@
|
||||||
// +build !linux
|
|
||||||
|
|
||||||
package netlink
|
|
||||||
|
|
||||||
func FouAdd(f Fou) error {
|
|
||||||
return ErrNotImplemented
|
|
||||||
}
|
|
||||||
|
|
||||||
func FouDel(f Fou) error {
|
|
||||||
return ErrNotImplemented
|
|
||||||
}
|
|
||||||
|
|
||||||
func FouList(fam int) ([]Fou, error) {
|
|
||||||
return nil, ErrNotImplemented
|
|
||||||
}
|
|
|
@ -5,7 +5,6 @@ import (
|
||||||
"syscall"
|
"syscall"
|
||||||
|
|
||||||
"github.com/vishvananda/netlink/nl"
|
"github.com/vishvananda/netlink/nl"
|
||||||
"golang.org/x/sys/unix"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type GenlOp struct {
|
type GenlOp struct {
|
||||||
|
@ -131,9 +130,9 @@ func (h *Handle) GenlFamilyList() ([]*GenlFamily, error) {
|
||||||
Command: nl.GENL_CTRL_CMD_GETFAMILY,
|
Command: nl.GENL_CTRL_CMD_GETFAMILY,
|
||||||
Version: nl.GENL_CTRL_VERSION,
|
Version: nl.GENL_CTRL_VERSION,
|
||||||
}
|
}
|
||||||
req := h.newNetlinkRequest(nl.GENL_ID_CTRL, unix.NLM_F_DUMP)
|
req := h.newNetlinkRequest(nl.GENL_ID_CTRL, syscall.NLM_F_DUMP)
|
||||||
req.AddData(msg)
|
req.AddData(msg)
|
||||||
msgs, err := req.Execute(unix.NETLINK_GENERIC, 0)
|
msgs, err := req.Execute(syscall.NETLINK_GENERIC, 0)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -152,7 +151,7 @@ func (h *Handle) GenlFamilyGet(name string) (*GenlFamily, error) {
|
||||||
req := h.newNetlinkRequest(nl.GENL_ID_CTRL, 0)
|
req := h.newNetlinkRequest(nl.GENL_ID_CTRL, 0)
|
||||||
req.AddData(msg)
|
req.AddData(msg)
|
||||||
req.AddData(nl.NewRtAttr(nl.GENL_CTRL_ATTR_FAMILY_NAME, nl.ZeroTerminated(name)))
|
req.AddData(nl.NewRtAttr(nl.GENL_CTRL_ATTR_FAMILY_NAME, nl.ZeroTerminated(name)))
|
||||||
msgs, err := req.Execute(unix.NETLINK_GENERIC, 0)
|
msgs, err := req.Execute(syscall.NETLINK_GENERIC, 0)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,7 +7,6 @@ import (
|
||||||
"syscall"
|
"syscall"
|
||||||
|
|
||||||
"github.com/vishvananda/netlink/nl"
|
"github.com/vishvananda/netlink/nl"
|
||||||
"golang.org/x/sys/unix"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type PDP struct {
|
type PDP struct {
|
||||||
|
@ -83,9 +82,9 @@ func (h *Handle) GTPPDPList() ([]*PDP, error) {
|
||||||
Command: nl.GENL_GTP_CMD_GETPDP,
|
Command: nl.GENL_GTP_CMD_GETPDP,
|
||||||
Version: nl.GENL_GTP_VERSION,
|
Version: nl.GENL_GTP_VERSION,
|
||||||
}
|
}
|
||||||
req := h.newNetlinkRequest(int(f.ID), unix.NLM_F_DUMP)
|
req := h.newNetlinkRequest(int(f.ID), syscall.NLM_F_DUMP)
|
||||||
req.AddData(msg)
|
req.AddData(msg)
|
||||||
msgs, err := req.Execute(unix.NETLINK_GENERIC, 0)
|
msgs, err := req.Execute(syscall.NETLINK_GENERIC, 0)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -97,7 +96,7 @@ func GTPPDPList() ([]*PDP, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func gtpPDPGet(req *nl.NetlinkRequest) (*PDP, error) {
|
func gtpPDPGet(req *nl.NetlinkRequest) (*PDP, error) {
|
||||||
msgs, err := req.Execute(unix.NETLINK_GENERIC, 0)
|
msgs, err := req.Execute(syscall.NETLINK_GENERIC, 0)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -183,7 +182,7 @@ func (h *Handle) GTPPDPAdd(link Link, pdp *PDP) error {
|
||||||
Command: nl.GENL_GTP_CMD_NEWPDP,
|
Command: nl.GENL_GTP_CMD_NEWPDP,
|
||||||
Version: nl.GENL_GTP_VERSION,
|
Version: nl.GENL_GTP_VERSION,
|
||||||
}
|
}
|
||||||
req := h.newNetlinkRequest(int(f.ID), unix.NLM_F_EXCL|unix.NLM_F_ACK)
|
req := h.newNetlinkRequest(int(f.ID), syscall.NLM_F_EXCL|syscall.NLM_F_ACK)
|
||||||
req.AddData(msg)
|
req.AddData(msg)
|
||||||
req.AddData(nl.NewRtAttr(nl.GENL_GTP_ATTR_VERSION, nl.Uint32Attr(pdp.Version)))
|
req.AddData(nl.NewRtAttr(nl.GENL_GTP_ATTR_VERSION, nl.Uint32Attr(pdp.Version)))
|
||||||
req.AddData(nl.NewRtAttr(nl.GENL_GTP_ATTR_LINK, nl.Uint32Attr(uint32(link.Attrs().Index))))
|
req.AddData(nl.NewRtAttr(nl.GENL_GTP_ATTR_LINK, nl.Uint32Attr(uint32(link.Attrs().Index))))
|
||||||
|
@ -200,7 +199,7 @@ func (h *Handle) GTPPDPAdd(link Link, pdp *PDP) error {
|
||||||
default:
|
default:
|
||||||
return fmt.Errorf("unsupported GTP version: %d", pdp.Version)
|
return fmt.Errorf("unsupported GTP version: %d", pdp.Version)
|
||||||
}
|
}
|
||||||
_, err = req.Execute(unix.NETLINK_GENERIC, 0)
|
_, err = req.Execute(syscall.NETLINK_GENERIC, 0)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -217,7 +216,7 @@ func (h *Handle) GTPPDPDel(link Link, pdp *PDP) error {
|
||||||
Command: nl.GENL_GTP_CMD_DELPDP,
|
Command: nl.GENL_GTP_CMD_DELPDP,
|
||||||
Version: nl.GENL_GTP_VERSION,
|
Version: nl.GENL_GTP_VERSION,
|
||||||
}
|
}
|
||||||
req := h.newNetlinkRequest(int(f.ID), unix.NLM_F_EXCL|unix.NLM_F_ACK)
|
req := h.newNetlinkRequest(int(f.ID), syscall.NLM_F_EXCL|syscall.NLM_F_ACK)
|
||||||
req.AddData(msg)
|
req.AddData(msg)
|
||||||
req.AddData(nl.NewRtAttr(nl.GENL_GTP_ATTR_VERSION, nl.Uint32Attr(pdp.Version)))
|
req.AddData(nl.NewRtAttr(nl.GENL_GTP_ATTR_VERSION, nl.Uint32Attr(pdp.Version)))
|
||||||
req.AddData(nl.NewRtAttr(nl.GENL_GTP_ATTR_LINK, nl.Uint32Attr(uint32(link.Attrs().Index))))
|
req.AddData(nl.NewRtAttr(nl.GENL_GTP_ATTR_LINK, nl.Uint32Attr(uint32(link.Attrs().Index))))
|
||||||
|
@ -230,7 +229,7 @@ func (h *Handle) GTPPDPDel(link Link, pdp *PDP) error {
|
||||||
default:
|
default:
|
||||||
return fmt.Errorf("unsupported GTP version: %d", pdp.Version)
|
return fmt.Errorf("unsupported GTP version: %d", pdp.Version)
|
||||||
}
|
}
|
||||||
_, err = req.Execute(unix.NETLINK_GENERIC, 0)
|
_, err = req.Execute(syscall.NETLINK_GENERIC, 0)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2,11 +2,11 @@ package netlink
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"syscall"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/vishvananda/netlink/nl"
|
"github.com/vishvananda/netlink/nl"
|
||||||
"github.com/vishvananda/netns"
|
"github.com/vishvananda/netns"
|
||||||
"golang.org/x/sys/unix"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// Empty handle used by the netlink package methods
|
// Empty handle used by the netlink package methods
|
||||||
|
@ -43,7 +43,7 @@ func (h *Handle) SetSocketTimeout(to time.Duration) error {
|
||||||
if to < time.Microsecond {
|
if to < time.Microsecond {
|
||||||
return fmt.Errorf("invalid timeout, minimul value is %s", time.Microsecond)
|
return fmt.Errorf("invalid timeout, minimul value is %s", time.Microsecond)
|
||||||
}
|
}
|
||||||
tv := unix.NsecToTimeval(to.Nanoseconds())
|
tv := syscall.NsecToTimeval(to.Nanoseconds())
|
||||||
for _, sh := range h.sockets {
|
for _, sh := range h.sockets {
|
||||||
if err := sh.Socket.SetSendTimeout(&tv); err != nil {
|
if err := sh.Socket.SetSendTimeout(&tv); err != nil {
|
||||||
return err
|
return err
|
||||||
|
@ -59,13 +59,13 @@ func (h *Handle) SetSocketTimeout(to time.Duration) error {
|
||||||
// socket in the netlink handle. The maximum value is capped by
|
// socket in the netlink handle. The maximum value is capped by
|
||||||
// /proc/sys/net/core/rmem_max.
|
// /proc/sys/net/core/rmem_max.
|
||||||
func (h *Handle) SetSocketReceiveBufferSize(size int, force bool) error {
|
func (h *Handle) SetSocketReceiveBufferSize(size int, force bool) error {
|
||||||
opt := unix.SO_RCVBUF
|
opt := syscall.SO_RCVBUF
|
||||||
if force {
|
if force {
|
||||||
opt = unix.SO_RCVBUFFORCE
|
opt = syscall.SO_RCVBUFFORCE
|
||||||
}
|
}
|
||||||
for _, sh := range h.sockets {
|
for _, sh := range h.sockets {
|
||||||
fd := sh.Socket.GetFd()
|
fd := sh.Socket.GetFd()
|
||||||
err := unix.SetsockoptInt(fd, unix.SOL_SOCKET, opt, size)
|
err := syscall.SetsockoptInt(fd, syscall.SOL_SOCKET, opt, size)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -81,7 +81,7 @@ func (h *Handle) GetSocketReceiveBufferSize() ([]int, error) {
|
||||||
i := 0
|
i := 0
|
||||||
for _, sh := range h.sockets {
|
for _, sh := range h.sockets {
|
||||||
fd := sh.Socket.GetFd()
|
fd := sh.Socket.GetFd()
|
||||||
size, err := unix.GetsockoptInt(fd, unix.SOL_SOCKET, unix.SO_RCVBUF)
|
size, err := syscall.GetsockoptInt(fd, syscall.SOL_SOCKET, syscall.SO_RCVBUF)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -134,10 +134,10 @@ func (h *Handle) newNetlinkRequest(proto, flags int) *nl.NetlinkRequest {
|
||||||
return nl.NewNetlinkRequest(proto, flags)
|
return nl.NewNetlinkRequest(proto, flags)
|
||||||
}
|
}
|
||||||
return &nl.NetlinkRequest{
|
return &nl.NetlinkRequest{
|
||||||
NlMsghdr: unix.NlMsghdr{
|
NlMsghdr: syscall.NlMsghdr{
|
||||||
Len: uint32(unix.SizeofNlMsghdr),
|
Len: uint32(syscall.SizeofNlMsghdr),
|
||||||
Type: uint16(proto),
|
Type: uint16(proto),
|
||||||
Flags: unix.NLM_F_REQUEST | uint16(flags),
|
Flags: syscall.NLM_F_REQUEST | uint16(flags),
|
||||||
},
|
},
|
||||||
Sockets: h.sockets,
|
Sockets: h.sockets,
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,7 +3,6 @@ package netlink
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"net"
|
"net"
|
||||||
"os"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// Link represents a link device from netlink. Shared link attributes
|
// Link represents a link device from netlink. Shared link attributes
|
||||||
|
@ -39,8 +38,6 @@ type LinkAttrs struct {
|
||||||
Protinfo *Protinfo
|
Protinfo *Protinfo
|
||||||
OperState LinkOperState
|
OperState LinkOperState
|
||||||
NetNsID int
|
NetNsID int
|
||||||
NumTxQueues int
|
|
||||||
NumRxQueues int
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// LinkOperState represents the values of the IFLA_OPERSTATE link
|
// LinkOperState represents the values of the IFLA_OPERSTATE link
|
||||||
|
@ -262,9 +259,6 @@ const (
|
||||||
type Macvlan struct {
|
type Macvlan struct {
|
||||||
LinkAttrs
|
LinkAttrs
|
||||||
Mode MacvlanMode
|
Mode MacvlanMode
|
||||||
|
|
||||||
// MACAddrs is only populated for Macvlan SOURCE links
|
|
||||||
MACAddrs []net.HardwareAddr
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (macvlan *Macvlan) Attrs() *LinkAttrs {
|
func (macvlan *Macvlan) Attrs() *LinkAttrs {
|
||||||
|
@ -290,10 +284,8 @@ type TuntapFlag uint16
|
||||||
// Tuntap links created via /dev/tun/tap, but can be destroyed via netlink
|
// Tuntap links created via /dev/tun/tap, but can be destroyed via netlink
|
||||||
type Tuntap struct {
|
type Tuntap struct {
|
||||||
LinkAttrs
|
LinkAttrs
|
||||||
Mode TuntapMode
|
Mode TuntapMode
|
||||||
Flags TuntapFlag
|
Flags TuntapFlag
|
||||||
Queues int
|
|
||||||
Fds []*os.File
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (tuntap *Tuntap) Attrs() *LinkAttrs {
|
func (tuntap *Tuntap) Attrs() *LinkAttrs {
|
||||||
|
@ -335,28 +327,26 @@ func (generic *GenericLink) Type() string {
|
||||||
|
|
||||||
type Vxlan struct {
|
type Vxlan struct {
|
||||||
LinkAttrs
|
LinkAttrs
|
||||||
VxlanId int
|
VxlanId int
|
||||||
VtepDevIndex int
|
VtepDevIndex int
|
||||||
SrcAddr net.IP
|
SrcAddr net.IP
|
||||||
Group net.IP
|
Group net.IP
|
||||||
TTL int
|
TTL int
|
||||||
TOS int
|
TOS int
|
||||||
Learning bool
|
Learning bool
|
||||||
Proxy bool
|
Proxy bool
|
||||||
RSC bool
|
RSC bool
|
||||||
L2miss bool
|
L2miss bool
|
||||||
L3miss bool
|
L3miss bool
|
||||||
UDPCSum bool
|
UDPCSum bool
|
||||||
UDP6ZeroCSumTx bool
|
NoAge bool
|
||||||
UDP6ZeroCSumRx bool
|
GBP bool
|
||||||
NoAge bool
|
FlowBased bool
|
||||||
GBP bool
|
Age int
|
||||||
FlowBased bool
|
Limit int
|
||||||
Age int
|
Port int
|
||||||
Limit int
|
PortLow int
|
||||||
Port int
|
PortHigh int
|
||||||
PortLow int
|
|
||||||
PortHigh int
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (vxlan *Vxlan) Attrs() *LinkAttrs {
|
func (vxlan *Vxlan) Attrs() *LinkAttrs {
|
||||||
|
@ -710,17 +700,12 @@ func (gretap *Gretap) Type() string {
|
||||||
|
|
||||||
type Iptun struct {
|
type Iptun struct {
|
||||||
LinkAttrs
|
LinkAttrs
|
||||||
Ttl uint8
|
Ttl uint8
|
||||||
Tos uint8
|
Tos uint8
|
||||||
PMtuDisc uint8
|
PMtuDisc uint8
|
||||||
Link uint32
|
Link uint32
|
||||||
Local net.IP
|
Local net.IP
|
||||||
Remote net.IP
|
Remote net.IP
|
||||||
EncapSport uint16
|
|
||||||
EncapDport uint16
|
|
||||||
EncapType uint16
|
|
||||||
EncapFlags uint16
|
|
||||||
FlowBased bool
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (iptun *Iptun) Attrs() *LinkAttrs {
|
func (iptun *Iptun) Attrs() *LinkAttrs {
|
||||||
|
@ -731,28 +716,6 @@ func (iptun *Iptun) Type() string {
|
||||||
return "ipip"
|
return "ipip"
|
||||||
}
|
}
|
||||||
|
|
||||||
type Sittun struct {
|
|
||||||
LinkAttrs
|
|
||||||
Link uint32
|
|
||||||
Local net.IP
|
|
||||||
Remote net.IP
|
|
||||||
Ttl uint8
|
|
||||||
Tos uint8
|
|
||||||
PMtuDisc uint8
|
|
||||||
EncapType uint16
|
|
||||||
EncapFlags uint16
|
|
||||||
EncapSport uint16
|
|
||||||
EncapDport uint16
|
|
||||||
}
|
|
||||||
|
|
||||||
func (sittun *Sittun) Attrs() *LinkAttrs {
|
|
||||||
return &sittun.LinkAttrs
|
|
||||||
}
|
|
||||||
|
|
||||||
func (sittun *Sittun) Type() string {
|
|
||||||
return "sit"
|
|
||||||
}
|
|
||||||
|
|
||||||
type Vti struct {
|
type Vti struct {
|
||||||
LinkAttrs
|
LinkAttrs
|
||||||
IKey uint32
|
IKey uint32
|
||||||
|
@ -772,20 +735,16 @@ func (iptun *Vti) Type() string {
|
||||||
|
|
||||||
type Gretun struct {
|
type Gretun struct {
|
||||||
LinkAttrs
|
LinkAttrs
|
||||||
Link uint32
|
Link uint32
|
||||||
IFlags uint16
|
IFlags uint16
|
||||||
OFlags uint16
|
OFlags uint16
|
||||||
IKey uint32
|
IKey uint32
|
||||||
OKey uint32
|
OKey uint32
|
||||||
Local net.IP
|
Local net.IP
|
||||||
Remote net.IP
|
Remote net.IP
|
||||||
Ttl uint8
|
Ttl uint8
|
||||||
Tos uint8
|
Tos uint8
|
||||||
PMtuDisc uint8
|
PMtuDisc uint8
|
||||||
EncapType uint16
|
|
||||||
EncapFlags uint16
|
|
||||||
EncapSport uint16
|
|
||||||
EncapDport uint16
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (gretun *Gretun) Attrs() *LinkAttrs {
|
func (gretun *Gretun) Attrs() *LinkAttrs {
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -15,8 +15,6 @@ type Neigh struct {
|
||||||
IP net.IP
|
IP net.IP
|
||||||
HardwareAddr net.HardwareAddr
|
HardwareAddr net.HardwareAddr
|
||||||
LLIPAddr net.IP //Used in the case of NHRP
|
LLIPAddr net.IP //Used in the case of NHRP
|
||||||
Vlan int
|
|
||||||
VNI int
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// String returns $ip/$hwaddr $label
|
// String returns $ip/$hwaddr $label
|
||||||
|
|
|
@ -2,10 +2,10 @@ package netlink
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"net"
|
"net"
|
||||||
|
"syscall"
|
||||||
"unsafe"
|
"unsafe"
|
||||||
|
|
||||||
"github.com/vishvananda/netlink/nl"
|
"github.com/vishvananda/netlink/nl"
|
||||||
"golang.org/x/sys/unix"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
@ -73,7 +73,7 @@ func NeighAdd(neigh *Neigh) error {
|
||||||
// NeighAdd will add an IP to MAC mapping to the ARP table
|
// NeighAdd will add an IP to MAC mapping to the ARP table
|
||||||
// Equivalent to: `ip neigh add ....`
|
// Equivalent to: `ip neigh add ....`
|
||||||
func (h *Handle) NeighAdd(neigh *Neigh) error {
|
func (h *Handle) NeighAdd(neigh *Neigh) error {
|
||||||
return h.neighAdd(neigh, unix.NLM_F_CREATE|unix.NLM_F_EXCL)
|
return h.neighAdd(neigh, syscall.NLM_F_CREATE|syscall.NLM_F_EXCL)
|
||||||
}
|
}
|
||||||
|
|
||||||
// NeighSet will add or replace an IP to MAC mapping to the ARP table
|
// NeighSet will add or replace an IP to MAC mapping to the ARP table
|
||||||
|
@ -85,7 +85,7 @@ func NeighSet(neigh *Neigh) error {
|
||||||
// NeighSet will add or replace an IP to MAC mapping to the ARP table
|
// NeighSet will add or replace an IP to MAC mapping to the ARP table
|
||||||
// Equivalent to: `ip neigh replace....`
|
// Equivalent to: `ip neigh replace....`
|
||||||
func (h *Handle) NeighSet(neigh *Neigh) error {
|
func (h *Handle) NeighSet(neigh *Neigh) error {
|
||||||
return h.neighAdd(neigh, unix.NLM_F_CREATE|unix.NLM_F_REPLACE)
|
return h.neighAdd(neigh, syscall.NLM_F_CREATE|syscall.NLM_F_REPLACE)
|
||||||
}
|
}
|
||||||
|
|
||||||
// NeighAppend will append an entry to FDB
|
// NeighAppend will append an entry to FDB
|
||||||
|
@ -97,7 +97,7 @@ func NeighAppend(neigh *Neigh) error {
|
||||||
// NeighAppend will append an entry to FDB
|
// NeighAppend will append an entry to FDB
|
||||||
// Equivalent to: `bridge fdb append...`
|
// Equivalent to: `bridge fdb append...`
|
||||||
func (h *Handle) NeighAppend(neigh *Neigh) error {
|
func (h *Handle) NeighAppend(neigh *Neigh) error {
|
||||||
return h.neighAdd(neigh, unix.NLM_F_CREATE|unix.NLM_F_APPEND)
|
return h.neighAdd(neigh, syscall.NLM_F_CREATE|syscall.NLM_F_APPEND)
|
||||||
}
|
}
|
||||||
|
|
||||||
// NeighAppend will append an entry to FDB
|
// NeighAppend will append an entry to FDB
|
||||||
|
@ -109,7 +109,7 @@ func neighAdd(neigh *Neigh, mode int) error {
|
||||||
// NeighAppend will append an entry to FDB
|
// NeighAppend will append an entry to FDB
|
||||||
// Equivalent to: `bridge fdb append...`
|
// Equivalent to: `bridge fdb append...`
|
||||||
func (h *Handle) neighAdd(neigh *Neigh, mode int) error {
|
func (h *Handle) neighAdd(neigh *Neigh, mode int) error {
|
||||||
req := h.newNetlinkRequest(unix.RTM_NEWNEIGH, mode|unix.NLM_F_ACK)
|
req := h.newNetlinkRequest(syscall.RTM_NEWNEIGH, mode|syscall.NLM_F_ACK)
|
||||||
return neighHandle(neigh, req)
|
return neighHandle(neigh, req)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -122,7 +122,7 @@ func NeighDel(neigh *Neigh) error {
|
||||||
// NeighDel will delete an IP address from a link device.
|
// NeighDel will delete an IP address from a link device.
|
||||||
// Equivalent to: `ip addr del $addr dev $link`
|
// Equivalent to: `ip addr del $addr dev $link`
|
||||||
func (h *Handle) NeighDel(neigh *Neigh) error {
|
func (h *Handle) NeighDel(neigh *Neigh) error {
|
||||||
req := h.newNetlinkRequest(unix.RTM_DELNEIGH, unix.NLM_F_ACK)
|
req := h.newNetlinkRequest(syscall.RTM_DELNEIGH, syscall.NLM_F_ACK)
|
||||||
return neighHandle(neigh, req)
|
return neighHandle(neigh, req)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -160,17 +160,7 @@ func neighHandle(neigh *Neigh, req *nl.NetlinkRequest) error {
|
||||||
req.AddData(hwData)
|
req.AddData(hwData)
|
||||||
}
|
}
|
||||||
|
|
||||||
if neigh.Vlan != 0 {
|
_, err := req.Execute(syscall.NETLINK_ROUTE, 0)
|
||||||
vlanData := nl.NewRtAttr(NDA_VLAN, nl.Uint16Attr(uint16(neigh.Vlan)))
|
|
||||||
req.AddData(vlanData)
|
|
||||||
}
|
|
||||||
|
|
||||||
if neigh.VNI != 0 {
|
|
||||||
vniData := nl.NewRtAttr(NDA_VNI, nl.Uint32Attr(uint32(neigh.VNI)))
|
|
||||||
req.AddData(vniData)
|
|
||||||
}
|
|
||||||
|
|
||||||
_, err := req.Execute(unix.NETLINK_ROUTE, 0)
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -203,7 +193,7 @@ func (h *Handle) NeighProxyList(linkIndex, family int) ([]Neigh, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *Handle) neighList(linkIndex, family, flags int) ([]Neigh, error) {
|
func (h *Handle) neighList(linkIndex, family, flags int) ([]Neigh, error) {
|
||||||
req := h.newNetlinkRequest(unix.RTM_GETNEIGH, unix.NLM_F_DUMP)
|
req := h.newNetlinkRequest(syscall.RTM_GETNEIGH, syscall.NLM_F_DUMP)
|
||||||
msg := Ndmsg{
|
msg := Ndmsg{
|
||||||
Family: uint8(family),
|
Family: uint8(family),
|
||||||
Index: uint32(linkIndex),
|
Index: uint32(linkIndex),
|
||||||
|
@ -211,7 +201,7 @@ func (h *Handle) neighList(linkIndex, family, flags int) ([]Neigh, error) {
|
||||||
}
|
}
|
||||||
req.AddData(&msg)
|
req.AddData(&msg)
|
||||||
|
|
||||||
msgs, err := req.Execute(unix.NETLINK_ROUTE, unix.RTM_NEWNEIGH)
|
msgs, err := req.Execute(syscall.NETLINK_ROUTE, syscall.RTM_NEWNEIGH)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -267,7 +257,7 @@ func NeighDeserialize(m []byte) (*Neigh, error) {
|
||||||
// BUG: Is this a bug in the netlink library?
|
// BUG: Is this a bug in the netlink library?
|
||||||
// #define RTA_LENGTH(len) (RTA_ALIGN(sizeof(struct rtattr)) + (len))
|
// #define RTA_LENGTH(len) (RTA_ALIGN(sizeof(struct rtattr)) + (len))
|
||||||
// #define RTA_PAYLOAD(rta) ((int)((rta)->rta_len) - RTA_LENGTH(0))
|
// #define RTA_PAYLOAD(rta) ((int)((rta)->rta_len) - RTA_LENGTH(0))
|
||||||
attrLen := attr.Attr.Len - unix.SizeofRtAttr
|
attrLen := attr.Attr.Len - syscall.SizeofRtAttr
|
||||||
if attrLen == 4 && (encapType == "ipip" ||
|
if attrLen == 4 && (encapType == "ipip" ||
|
||||||
encapType == "sit" ||
|
encapType == "sit" ||
|
||||||
encapType == "gre") {
|
encapType == "gre") {
|
||||||
|
@ -278,10 +268,6 @@ func NeighDeserialize(m []byte) (*Neigh, error) {
|
||||||
} else {
|
} else {
|
||||||
neigh.HardwareAddr = net.HardwareAddr(attr.Value)
|
neigh.HardwareAddr = net.HardwareAddr(attr.Value)
|
||||||
}
|
}
|
||||||
case NDA_VLAN:
|
|
||||||
neigh.Vlan = int(native.Uint16(attr.Value[0:2]))
|
|
||||||
case NDA_VNI:
|
|
||||||
neigh.VNI = int(native.Uint32(attr.Value[0:4]))
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -12,7 +12,6 @@ go_library(
|
||||||
"nl_linux.go",
|
"nl_linux.go",
|
||||||
"nl_unspecified.go",
|
"nl_unspecified.go",
|
||||||
"route_linux.go",
|
"route_linux.go",
|
||||||
"seg6_linux.go",
|
|
||||||
"syscall.go",
|
"syscall.go",
|
||||||
"tc_linux.go",
|
"tc_linux.go",
|
||||||
"xfrm_linux.go",
|
"xfrm_linux.go",
|
||||||
|
@ -26,7 +25,6 @@ go_library(
|
||||||
deps = select({
|
deps = select({
|
||||||
"@io_bazel_rules_go//go/platform:linux": [
|
"@io_bazel_rules_go//go/platform:linux": [
|
||||||
"//vendor/github.com/vishvananda/netns:go_default_library",
|
"//vendor/github.com/vishvananda/netns:go_default_library",
|
||||||
"//vendor/golang.org/x/sys/unix:go_default_library",
|
|
||||||
],
|
],
|
||||||
"//conditions:default": [],
|
"//conditions:default": [],
|
||||||
}),
|
}),
|
||||||
|
|
|
@ -1,18 +1,17 @@
|
||||||
package nl
|
package nl
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"syscall"
|
||||||
"unsafe"
|
"unsafe"
|
||||||
|
|
||||||
"golang.org/x/sys/unix"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type IfAddrmsg struct {
|
type IfAddrmsg struct {
|
||||||
unix.IfAddrmsg
|
syscall.IfAddrmsg
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewIfAddrmsg(family int) *IfAddrmsg {
|
func NewIfAddrmsg(family int) *IfAddrmsg {
|
||||||
return &IfAddrmsg{
|
return &IfAddrmsg{
|
||||||
IfAddrmsg: unix.IfAddrmsg{
|
IfAddrmsg: syscall.IfAddrmsg{
|
||||||
Family: uint8(family),
|
Family: uint8(family),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
@ -36,15 +35,15 @@ func NewIfAddrmsg(family int) *IfAddrmsg {
|
||||||
// SizeofIfAddrmsg = 0x8
|
// SizeofIfAddrmsg = 0x8
|
||||||
|
|
||||||
func DeserializeIfAddrmsg(b []byte) *IfAddrmsg {
|
func DeserializeIfAddrmsg(b []byte) *IfAddrmsg {
|
||||||
return (*IfAddrmsg)(unsafe.Pointer(&b[0:unix.SizeofIfAddrmsg][0]))
|
return (*IfAddrmsg)(unsafe.Pointer(&b[0:syscall.SizeofIfAddrmsg][0]))
|
||||||
}
|
}
|
||||||
|
|
||||||
func (msg *IfAddrmsg) Serialize() []byte {
|
func (msg *IfAddrmsg) Serialize() []byte {
|
||||||
return (*(*[unix.SizeofIfAddrmsg]byte)(unsafe.Pointer(msg)))[:]
|
return (*(*[syscall.SizeofIfAddrmsg]byte)(unsafe.Pointer(msg)))[:]
|
||||||
}
|
}
|
||||||
|
|
||||||
func (msg *IfAddrmsg) Len() int {
|
func (msg *IfAddrmsg) Len() int {
|
||||||
return unix.SizeofIfAddrmsg
|
return syscall.SizeofIfAddrmsg
|
||||||
}
|
}
|
||||||
|
|
||||||
// struct ifa_cacheinfo {
|
// struct ifa_cacheinfo {
|
||||||
|
|
|
@ -1,15 +1,14 @@
|
||||||
package nl
|
package nl
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"syscall"
|
||||||
"unsafe"
|
"unsafe"
|
||||||
|
|
||||||
"golang.org/x/sys/unix"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
DEFAULT_CHANGE = 0xFFFFFFFF
|
DEFAULT_CHANGE = 0xFFFFFFFF
|
||||||
// doesn't exist in syscall
|
// doesn't exist in syscall
|
||||||
IFLA_VFINFO_LIST = unix.IFLA_IFALIAS + 1 + iota
|
IFLA_VFINFO_LIST = syscall.IFLA_IFALIAS + 1 + iota
|
||||||
IFLA_STATS64
|
IFLA_STATS64
|
||||||
IFLA_VF_PORTS
|
IFLA_VF_PORTS
|
||||||
IFLA_PORT_SELF
|
IFLA_PORT_SELF
|
||||||
|
@ -119,10 +118,6 @@ const (
|
||||||
IFLA_MACVLAN_UNSPEC = iota
|
IFLA_MACVLAN_UNSPEC = iota
|
||||||
IFLA_MACVLAN_MODE
|
IFLA_MACVLAN_MODE
|
||||||
IFLA_MACVLAN_FLAGS
|
IFLA_MACVLAN_FLAGS
|
||||||
IFLA_MACVLAN_MACADDR_MODE
|
|
||||||
IFLA_MACVLAN_MACADDR
|
|
||||||
IFLA_MACVLAN_MACADDR_DATA
|
|
||||||
IFLA_MACVLAN_MACADDR_COUNT
|
|
||||||
IFLA_MACVLAN_MAX = IFLA_MACVLAN_FLAGS
|
IFLA_MACVLAN_MAX = IFLA_MACVLAN_FLAGS
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -134,13 +129,6 @@ const (
|
||||||
MACVLAN_MODE_SOURCE = 16
|
MACVLAN_MODE_SOURCE = 16
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
|
||||||
MACVLAN_MACADDR_ADD = iota
|
|
||||||
MACVLAN_MACADDR_DEL
|
|
||||||
MACVLAN_MACADDR_FLUSH
|
|
||||||
MACVLAN_MACADDR_SET
|
|
||||||
)
|
|
||||||
|
|
||||||
const (
|
const (
|
||||||
IFLA_BOND_UNSPEC = iota
|
IFLA_BOND_UNSPEC = iota
|
||||||
IFLA_BOND_MODE
|
IFLA_BOND_MODE
|
||||||
|
@ -487,12 +475,7 @@ const (
|
||||||
IFLA_IPTUN_6RD_RELAY_PREFIX
|
IFLA_IPTUN_6RD_RELAY_PREFIX
|
||||||
IFLA_IPTUN_6RD_PREFIXLEN
|
IFLA_IPTUN_6RD_PREFIXLEN
|
||||||
IFLA_IPTUN_6RD_RELAY_PREFIXLEN
|
IFLA_IPTUN_6RD_RELAY_PREFIXLEN
|
||||||
IFLA_IPTUN_ENCAP_TYPE
|
IFLA_IPTUN_MAX = IFLA_IPTUN_6RD_RELAY_PREFIXLEN
|
||||||
IFLA_IPTUN_ENCAP_FLAGS
|
|
||||||
IFLA_IPTUN_ENCAP_SPORT
|
|
||||||
IFLA_IPTUN_ENCAP_DPORT
|
|
||||||
IFLA_IPTUN_COLLECT_METADATA
|
|
||||||
IFLA_IPTUN_MAX = IFLA_IPTUN_COLLECT_METADATA
|
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
|
|
@ -13,19 +13,18 @@ import (
|
||||||
"unsafe"
|
"unsafe"
|
||||||
|
|
||||||
"github.com/vishvananda/netns"
|
"github.com/vishvananda/netns"
|
||||||
"golang.org/x/sys/unix"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
// Family type definitions
|
// Family type definitions
|
||||||
FAMILY_ALL = unix.AF_UNSPEC
|
FAMILY_ALL = syscall.AF_UNSPEC
|
||||||
FAMILY_V4 = unix.AF_INET
|
FAMILY_V4 = syscall.AF_INET
|
||||||
FAMILY_V6 = unix.AF_INET6
|
FAMILY_V6 = syscall.AF_INET6
|
||||||
FAMILY_MPLS = AF_MPLS
|
FAMILY_MPLS = AF_MPLS
|
||||||
)
|
)
|
||||||
|
|
||||||
// SupportedNlFamilies contains the list of netlink families this netlink package supports
|
// SupportedNlFamilies contains the list of netlink families this netlink package supports
|
||||||
var SupportedNlFamilies = []int{unix.NETLINK_ROUTE, unix.NETLINK_XFRM, unix.NETLINK_NETFILTER}
|
var SupportedNlFamilies = []int{syscall.NETLINK_ROUTE, syscall.NETLINK_XFRM, syscall.NETLINK_NETFILTER}
|
||||||
|
|
||||||
var nextSeqNr uint32
|
var nextSeqNr uint32
|
||||||
|
|
||||||
|
@ -78,161 +77,161 @@ type NetlinkRequestData interface {
|
||||||
|
|
||||||
// IfInfomsg is related to links, but it is used for list requests as well
|
// IfInfomsg is related to links, but it is used for list requests as well
|
||||||
type IfInfomsg struct {
|
type IfInfomsg struct {
|
||||||
unix.IfInfomsg
|
syscall.IfInfomsg
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create an IfInfomsg with family specified
|
// Create an IfInfomsg with family specified
|
||||||
func NewIfInfomsg(family int) *IfInfomsg {
|
func NewIfInfomsg(family int) *IfInfomsg {
|
||||||
return &IfInfomsg{
|
return &IfInfomsg{
|
||||||
IfInfomsg: unix.IfInfomsg{
|
IfInfomsg: syscall.IfInfomsg{
|
||||||
Family: uint8(family),
|
Family: uint8(family),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func DeserializeIfInfomsg(b []byte) *IfInfomsg {
|
func DeserializeIfInfomsg(b []byte) *IfInfomsg {
|
||||||
return (*IfInfomsg)(unsafe.Pointer(&b[0:unix.SizeofIfInfomsg][0]))
|
return (*IfInfomsg)(unsafe.Pointer(&b[0:syscall.SizeofIfInfomsg][0]))
|
||||||
}
|
}
|
||||||
|
|
||||||
func (msg *IfInfomsg) Serialize() []byte {
|
func (msg *IfInfomsg) Serialize() []byte {
|
||||||
return (*(*[unix.SizeofIfInfomsg]byte)(unsafe.Pointer(msg)))[:]
|
return (*(*[syscall.SizeofIfInfomsg]byte)(unsafe.Pointer(msg)))[:]
|
||||||
}
|
}
|
||||||
|
|
||||||
func (msg *IfInfomsg) Len() int {
|
func (msg *IfInfomsg) Len() int {
|
||||||
return unix.SizeofIfInfomsg
|
return syscall.SizeofIfInfomsg
|
||||||
}
|
}
|
||||||
|
|
||||||
func (msg *IfInfomsg) EncapType() string {
|
func (msg *IfInfomsg) EncapType() string {
|
||||||
switch msg.Type {
|
switch msg.Type {
|
||||||
case 0:
|
case 0:
|
||||||
return "generic"
|
return "generic"
|
||||||
case unix.ARPHRD_ETHER:
|
case syscall.ARPHRD_ETHER:
|
||||||
return "ether"
|
return "ether"
|
||||||
case unix.ARPHRD_EETHER:
|
case syscall.ARPHRD_EETHER:
|
||||||
return "eether"
|
return "eether"
|
||||||
case unix.ARPHRD_AX25:
|
case syscall.ARPHRD_AX25:
|
||||||
return "ax25"
|
return "ax25"
|
||||||
case unix.ARPHRD_PRONET:
|
case syscall.ARPHRD_PRONET:
|
||||||
return "pronet"
|
return "pronet"
|
||||||
case unix.ARPHRD_CHAOS:
|
case syscall.ARPHRD_CHAOS:
|
||||||
return "chaos"
|
return "chaos"
|
||||||
case unix.ARPHRD_IEEE802:
|
case syscall.ARPHRD_IEEE802:
|
||||||
return "ieee802"
|
return "ieee802"
|
||||||
case unix.ARPHRD_ARCNET:
|
case syscall.ARPHRD_ARCNET:
|
||||||
return "arcnet"
|
return "arcnet"
|
||||||
case unix.ARPHRD_APPLETLK:
|
case syscall.ARPHRD_APPLETLK:
|
||||||
return "atalk"
|
return "atalk"
|
||||||
case unix.ARPHRD_DLCI:
|
case syscall.ARPHRD_DLCI:
|
||||||
return "dlci"
|
return "dlci"
|
||||||
case unix.ARPHRD_ATM:
|
case syscall.ARPHRD_ATM:
|
||||||
return "atm"
|
return "atm"
|
||||||
case unix.ARPHRD_METRICOM:
|
case syscall.ARPHRD_METRICOM:
|
||||||
return "metricom"
|
return "metricom"
|
||||||
case unix.ARPHRD_IEEE1394:
|
case syscall.ARPHRD_IEEE1394:
|
||||||
return "ieee1394"
|
return "ieee1394"
|
||||||
case unix.ARPHRD_INFINIBAND:
|
case syscall.ARPHRD_INFINIBAND:
|
||||||
return "infiniband"
|
return "infiniband"
|
||||||
case unix.ARPHRD_SLIP:
|
case syscall.ARPHRD_SLIP:
|
||||||
return "slip"
|
return "slip"
|
||||||
case unix.ARPHRD_CSLIP:
|
case syscall.ARPHRD_CSLIP:
|
||||||
return "cslip"
|
return "cslip"
|
||||||
case unix.ARPHRD_SLIP6:
|
case syscall.ARPHRD_SLIP6:
|
||||||
return "slip6"
|
return "slip6"
|
||||||
case unix.ARPHRD_CSLIP6:
|
case syscall.ARPHRD_CSLIP6:
|
||||||
return "cslip6"
|
return "cslip6"
|
||||||
case unix.ARPHRD_RSRVD:
|
case syscall.ARPHRD_RSRVD:
|
||||||
return "rsrvd"
|
return "rsrvd"
|
||||||
case unix.ARPHRD_ADAPT:
|
case syscall.ARPHRD_ADAPT:
|
||||||
return "adapt"
|
return "adapt"
|
||||||
case unix.ARPHRD_ROSE:
|
case syscall.ARPHRD_ROSE:
|
||||||
return "rose"
|
return "rose"
|
||||||
case unix.ARPHRD_X25:
|
case syscall.ARPHRD_X25:
|
||||||
return "x25"
|
return "x25"
|
||||||
case unix.ARPHRD_HWX25:
|
case syscall.ARPHRD_HWX25:
|
||||||
return "hwx25"
|
return "hwx25"
|
||||||
case unix.ARPHRD_PPP:
|
case syscall.ARPHRD_PPP:
|
||||||
return "ppp"
|
return "ppp"
|
||||||
case unix.ARPHRD_HDLC:
|
case syscall.ARPHRD_HDLC:
|
||||||
return "hdlc"
|
return "hdlc"
|
||||||
case unix.ARPHRD_LAPB:
|
case syscall.ARPHRD_LAPB:
|
||||||
return "lapb"
|
return "lapb"
|
||||||
case unix.ARPHRD_DDCMP:
|
case syscall.ARPHRD_DDCMP:
|
||||||
return "ddcmp"
|
return "ddcmp"
|
||||||
case unix.ARPHRD_RAWHDLC:
|
case syscall.ARPHRD_RAWHDLC:
|
||||||
return "rawhdlc"
|
return "rawhdlc"
|
||||||
case unix.ARPHRD_TUNNEL:
|
case syscall.ARPHRD_TUNNEL:
|
||||||
return "ipip"
|
return "ipip"
|
||||||
case unix.ARPHRD_TUNNEL6:
|
case syscall.ARPHRD_TUNNEL6:
|
||||||
return "tunnel6"
|
return "tunnel6"
|
||||||
case unix.ARPHRD_FRAD:
|
case syscall.ARPHRD_FRAD:
|
||||||
return "frad"
|
return "frad"
|
||||||
case unix.ARPHRD_SKIP:
|
case syscall.ARPHRD_SKIP:
|
||||||
return "skip"
|
return "skip"
|
||||||
case unix.ARPHRD_LOOPBACK:
|
case syscall.ARPHRD_LOOPBACK:
|
||||||
return "loopback"
|
return "loopback"
|
||||||
case unix.ARPHRD_LOCALTLK:
|
case syscall.ARPHRD_LOCALTLK:
|
||||||
return "ltalk"
|
return "ltalk"
|
||||||
case unix.ARPHRD_FDDI:
|
case syscall.ARPHRD_FDDI:
|
||||||
return "fddi"
|
return "fddi"
|
||||||
case unix.ARPHRD_BIF:
|
case syscall.ARPHRD_BIF:
|
||||||
return "bif"
|
return "bif"
|
||||||
case unix.ARPHRD_SIT:
|
case syscall.ARPHRD_SIT:
|
||||||
return "sit"
|
return "sit"
|
||||||
case unix.ARPHRD_IPDDP:
|
case syscall.ARPHRD_IPDDP:
|
||||||
return "ip/ddp"
|
return "ip/ddp"
|
||||||
case unix.ARPHRD_IPGRE:
|
case syscall.ARPHRD_IPGRE:
|
||||||
return "gre"
|
return "gre"
|
||||||
case unix.ARPHRD_PIMREG:
|
case syscall.ARPHRD_PIMREG:
|
||||||
return "pimreg"
|
return "pimreg"
|
||||||
case unix.ARPHRD_HIPPI:
|
case syscall.ARPHRD_HIPPI:
|
||||||
return "hippi"
|
return "hippi"
|
||||||
case unix.ARPHRD_ASH:
|
case syscall.ARPHRD_ASH:
|
||||||
return "ash"
|
return "ash"
|
||||||
case unix.ARPHRD_ECONET:
|
case syscall.ARPHRD_ECONET:
|
||||||
return "econet"
|
return "econet"
|
||||||
case unix.ARPHRD_IRDA:
|
case syscall.ARPHRD_IRDA:
|
||||||
return "irda"
|
return "irda"
|
||||||
case unix.ARPHRD_FCPP:
|
case syscall.ARPHRD_FCPP:
|
||||||
return "fcpp"
|
return "fcpp"
|
||||||
case unix.ARPHRD_FCAL:
|
case syscall.ARPHRD_FCAL:
|
||||||
return "fcal"
|
return "fcal"
|
||||||
case unix.ARPHRD_FCPL:
|
case syscall.ARPHRD_FCPL:
|
||||||
return "fcpl"
|
return "fcpl"
|
||||||
case unix.ARPHRD_FCFABRIC:
|
case syscall.ARPHRD_FCFABRIC:
|
||||||
return "fcfb0"
|
return "fcfb0"
|
||||||
case unix.ARPHRD_FCFABRIC + 1:
|
case syscall.ARPHRD_FCFABRIC + 1:
|
||||||
return "fcfb1"
|
return "fcfb1"
|
||||||
case unix.ARPHRD_FCFABRIC + 2:
|
case syscall.ARPHRD_FCFABRIC + 2:
|
||||||
return "fcfb2"
|
return "fcfb2"
|
||||||
case unix.ARPHRD_FCFABRIC + 3:
|
case syscall.ARPHRD_FCFABRIC + 3:
|
||||||
return "fcfb3"
|
return "fcfb3"
|
||||||
case unix.ARPHRD_FCFABRIC + 4:
|
case syscall.ARPHRD_FCFABRIC + 4:
|
||||||
return "fcfb4"
|
return "fcfb4"
|
||||||
case unix.ARPHRD_FCFABRIC + 5:
|
case syscall.ARPHRD_FCFABRIC + 5:
|
||||||
return "fcfb5"
|
return "fcfb5"
|
||||||
case unix.ARPHRD_FCFABRIC + 6:
|
case syscall.ARPHRD_FCFABRIC + 6:
|
||||||
return "fcfb6"
|
return "fcfb6"
|
||||||
case unix.ARPHRD_FCFABRIC + 7:
|
case syscall.ARPHRD_FCFABRIC + 7:
|
||||||
return "fcfb7"
|
return "fcfb7"
|
||||||
case unix.ARPHRD_FCFABRIC + 8:
|
case syscall.ARPHRD_FCFABRIC + 8:
|
||||||
return "fcfb8"
|
return "fcfb8"
|
||||||
case unix.ARPHRD_FCFABRIC + 9:
|
case syscall.ARPHRD_FCFABRIC + 9:
|
||||||
return "fcfb9"
|
return "fcfb9"
|
||||||
case unix.ARPHRD_FCFABRIC + 10:
|
case syscall.ARPHRD_FCFABRIC + 10:
|
||||||
return "fcfb10"
|
return "fcfb10"
|
||||||
case unix.ARPHRD_FCFABRIC + 11:
|
case syscall.ARPHRD_FCFABRIC + 11:
|
||||||
return "fcfb11"
|
return "fcfb11"
|
||||||
case unix.ARPHRD_FCFABRIC + 12:
|
case syscall.ARPHRD_FCFABRIC + 12:
|
||||||
return "fcfb12"
|
return "fcfb12"
|
||||||
case unix.ARPHRD_IEEE802_TR:
|
case syscall.ARPHRD_IEEE802_TR:
|
||||||
return "tr"
|
return "tr"
|
||||||
case unix.ARPHRD_IEEE80211:
|
case syscall.ARPHRD_IEEE80211:
|
||||||
return "ieee802.11"
|
return "ieee802.11"
|
||||||
case unix.ARPHRD_IEEE80211_PRISM:
|
case syscall.ARPHRD_IEEE80211_PRISM:
|
||||||
return "ieee802.11/prism"
|
return "ieee802.11/prism"
|
||||||
case unix.ARPHRD_IEEE80211_RADIOTAP:
|
case syscall.ARPHRD_IEEE80211_RADIOTAP:
|
||||||
return "ieee802.11/radiotap"
|
return "ieee802.11/radiotap"
|
||||||
case unix.ARPHRD_IEEE802154:
|
case syscall.ARPHRD_IEEE802154:
|
||||||
return "ieee802.15.4"
|
return "ieee802.15.4"
|
||||||
|
|
||||||
case 65534:
|
case 65534:
|
||||||
|
@ -244,7 +243,7 @@ func (msg *IfInfomsg) EncapType() string {
|
||||||
}
|
}
|
||||||
|
|
||||||
func rtaAlignOf(attrlen int) int {
|
func rtaAlignOf(attrlen int) int {
|
||||||
return (attrlen + unix.RTA_ALIGNTO - 1) & ^(unix.RTA_ALIGNTO - 1)
|
return (attrlen + syscall.RTA_ALIGNTO - 1) & ^(syscall.RTA_ALIGNTO - 1)
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewIfInfomsgChild(parent *RtAttr, family int) *IfInfomsg {
|
func NewIfInfomsgChild(parent *RtAttr, family int) *IfInfomsg {
|
||||||
|
@ -255,7 +254,7 @@ func NewIfInfomsgChild(parent *RtAttr, family int) *IfInfomsg {
|
||||||
|
|
||||||
// Extend RtAttr to handle data and children
|
// Extend RtAttr to handle data and children
|
||||||
type RtAttr struct {
|
type RtAttr struct {
|
||||||
unix.RtAttr
|
syscall.RtAttr
|
||||||
Data []byte
|
Data []byte
|
||||||
children []NetlinkRequestData
|
children []NetlinkRequestData
|
||||||
}
|
}
|
||||||
|
@ -263,7 +262,7 @@ type RtAttr struct {
|
||||||
// Create a new Extended RtAttr object
|
// Create a new Extended RtAttr object
|
||||||
func NewRtAttr(attrType int, data []byte) *RtAttr {
|
func NewRtAttr(attrType int, data []byte) *RtAttr {
|
||||||
return &RtAttr{
|
return &RtAttr{
|
||||||
RtAttr: unix.RtAttr{
|
RtAttr: syscall.RtAttr{
|
||||||
Type: uint16(attrType),
|
Type: uint16(attrType),
|
||||||
},
|
},
|
||||||
children: []NetlinkRequestData{},
|
children: []NetlinkRequestData{},
|
||||||
|
@ -278,21 +277,16 @@ func NewRtAttrChild(parent *RtAttr, attrType int, data []byte) *RtAttr {
|
||||||
return attr
|
return attr
|
||||||
}
|
}
|
||||||
|
|
||||||
// AddChild adds an existing RtAttr as a child.
|
|
||||||
func (a *RtAttr) AddChild(attr *RtAttr) {
|
|
||||||
a.children = append(a.children, attr)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (a *RtAttr) Len() int {
|
func (a *RtAttr) Len() int {
|
||||||
if len(a.children) == 0 {
|
if len(a.children) == 0 {
|
||||||
return (unix.SizeofRtAttr + len(a.Data))
|
return (syscall.SizeofRtAttr + len(a.Data))
|
||||||
}
|
}
|
||||||
|
|
||||||
l := 0
|
l := 0
|
||||||
for _, child := range a.children {
|
for _, child := range a.children {
|
||||||
l += rtaAlignOf(child.Len())
|
l += rtaAlignOf(child.Len())
|
||||||
}
|
}
|
||||||
l += unix.SizeofRtAttr
|
l += syscall.SizeofRtAttr
|
||||||
return rtaAlignOf(l + len(a.Data))
|
return rtaAlignOf(l + len(a.Data))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -325,7 +319,7 @@ func (a *RtAttr) Serialize() []byte {
|
||||||
}
|
}
|
||||||
|
|
||||||
type NetlinkRequest struct {
|
type NetlinkRequest struct {
|
||||||
unix.NlMsghdr
|
syscall.NlMsghdr
|
||||||
Data []NetlinkRequestData
|
Data []NetlinkRequestData
|
||||||
RawData []byte
|
RawData []byte
|
||||||
Sockets map[int]*SocketHandle
|
Sockets map[int]*SocketHandle
|
||||||
|
@ -333,7 +327,7 @@ type NetlinkRequest struct {
|
||||||
|
|
||||||
// Serialize the Netlink Request into a byte array
|
// Serialize the Netlink Request into a byte array
|
||||||
func (req *NetlinkRequest) Serialize() []byte {
|
func (req *NetlinkRequest) Serialize() []byte {
|
||||||
length := unix.SizeofNlMsghdr
|
length := syscall.SizeofNlMsghdr
|
||||||
dataBytes := make([][]byte, len(req.Data))
|
dataBytes := make([][]byte, len(req.Data))
|
||||||
for i, data := range req.Data {
|
for i, data := range req.Data {
|
||||||
dataBytes[i] = data.Serialize()
|
dataBytes[i] = data.Serialize()
|
||||||
|
@ -343,8 +337,8 @@ func (req *NetlinkRequest) Serialize() []byte {
|
||||||
|
|
||||||
req.Len = uint32(length)
|
req.Len = uint32(length)
|
||||||
b := make([]byte, length)
|
b := make([]byte, length)
|
||||||
hdr := (*(*[unix.SizeofNlMsghdr]byte)(unsafe.Pointer(req)))[:]
|
hdr := (*(*[syscall.SizeofNlMsghdr]byte)(unsafe.Pointer(req)))[:]
|
||||||
next := unix.SizeofNlMsghdr
|
next := syscall.SizeofNlMsghdr
|
||||||
copy(b[0:next], hdr)
|
copy(b[0:next], hdr)
|
||||||
for _, data := range dataBytes {
|
for _, data := range dataBytes {
|
||||||
for _, dataByte := range data {
|
for _, dataByte := range data {
|
||||||
|
@ -427,10 +421,10 @@ done:
|
||||||
if m.Header.Pid != pid {
|
if m.Header.Pid != pid {
|
||||||
return nil, fmt.Errorf("Wrong pid %d, expected %d", m.Header.Pid, pid)
|
return nil, fmt.Errorf("Wrong pid %d, expected %d", m.Header.Pid, pid)
|
||||||
}
|
}
|
||||||
if m.Header.Type == unix.NLMSG_DONE {
|
if m.Header.Type == syscall.NLMSG_DONE {
|
||||||
break done
|
break done
|
||||||
}
|
}
|
||||||
if m.Header.Type == unix.NLMSG_ERROR {
|
if m.Header.Type == syscall.NLMSG_ERROR {
|
||||||
native := NativeEndian()
|
native := NativeEndian()
|
||||||
error := int32(native.Uint32(m.Data[0:4]))
|
error := int32(native.Uint32(m.Data[0:4]))
|
||||||
if error == 0 {
|
if error == 0 {
|
||||||
|
@ -442,7 +436,7 @@ done:
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
res = append(res, m.Data)
|
res = append(res, m.Data)
|
||||||
if m.Header.Flags&unix.NLM_F_MULTI == 0 {
|
if m.Header.Flags&syscall.NLM_F_MULTI == 0 {
|
||||||
break done
|
break done
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -455,10 +449,10 @@ done:
|
||||||
// the message is serialized
|
// the message is serialized
|
||||||
func NewNetlinkRequest(proto, flags int) *NetlinkRequest {
|
func NewNetlinkRequest(proto, flags int) *NetlinkRequest {
|
||||||
return &NetlinkRequest{
|
return &NetlinkRequest{
|
||||||
NlMsghdr: unix.NlMsghdr{
|
NlMsghdr: syscall.NlMsghdr{
|
||||||
Len: uint32(unix.SizeofNlMsghdr),
|
Len: uint32(syscall.SizeofNlMsghdr),
|
||||||
Type: uint16(proto),
|
Type: uint16(proto),
|
||||||
Flags: unix.NLM_F_REQUEST | uint16(flags),
|
Flags: syscall.NLM_F_REQUEST | uint16(flags),
|
||||||
Seq: atomic.AddUint32(&nextSeqNr, 1),
|
Seq: atomic.AddUint32(&nextSeqNr, 1),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
@ -466,21 +460,21 @@ func NewNetlinkRequest(proto, flags int) *NetlinkRequest {
|
||||||
|
|
||||||
type NetlinkSocket struct {
|
type NetlinkSocket struct {
|
||||||
fd int32
|
fd int32
|
||||||
lsa unix.SockaddrNetlink
|
lsa syscall.SockaddrNetlink
|
||||||
sync.Mutex
|
sync.Mutex
|
||||||
}
|
}
|
||||||
|
|
||||||
func getNetlinkSocket(protocol int) (*NetlinkSocket, error) {
|
func getNetlinkSocket(protocol int) (*NetlinkSocket, error) {
|
||||||
fd, err := unix.Socket(unix.AF_NETLINK, unix.SOCK_RAW|unix.SOCK_CLOEXEC, protocol)
|
fd, err := syscall.Socket(syscall.AF_NETLINK, syscall.SOCK_RAW|syscall.SOCK_CLOEXEC, protocol)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
s := &NetlinkSocket{
|
s := &NetlinkSocket{
|
||||||
fd: int32(fd),
|
fd: int32(fd),
|
||||||
}
|
}
|
||||||
s.lsa.Family = unix.AF_NETLINK
|
s.lsa.Family = syscall.AF_NETLINK
|
||||||
if err := unix.Bind(fd, &s.lsa); err != nil {
|
if err := syscall.Bind(fd, &s.lsa); err != nil {
|
||||||
unix.Close(fd)
|
syscall.Close(fd)
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -557,21 +551,21 @@ func executeInNetns(newNs, curNs netns.NsHandle) (func(), error) {
|
||||||
// Returns the netlink socket on which Receive() method can be called
|
// Returns the netlink socket on which Receive() method can be called
|
||||||
// to retrieve the messages from the kernel.
|
// to retrieve the messages from the kernel.
|
||||||
func Subscribe(protocol int, groups ...uint) (*NetlinkSocket, error) {
|
func Subscribe(protocol int, groups ...uint) (*NetlinkSocket, error) {
|
||||||
fd, err := unix.Socket(unix.AF_NETLINK, unix.SOCK_RAW, protocol)
|
fd, err := syscall.Socket(syscall.AF_NETLINK, syscall.SOCK_RAW, protocol)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
s := &NetlinkSocket{
|
s := &NetlinkSocket{
|
||||||
fd: int32(fd),
|
fd: int32(fd),
|
||||||
}
|
}
|
||||||
s.lsa.Family = unix.AF_NETLINK
|
s.lsa.Family = syscall.AF_NETLINK
|
||||||
|
|
||||||
for _, g := range groups {
|
for _, g := range groups {
|
||||||
s.lsa.Groups |= (1 << (g - 1))
|
s.lsa.Groups |= (1 << (g - 1))
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := unix.Bind(fd, &s.lsa); err != nil {
|
if err := syscall.Bind(fd, &s.lsa); err != nil {
|
||||||
unix.Close(fd)
|
syscall.Close(fd)
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -592,7 +586,7 @@ func SubscribeAt(newNs, curNs netns.NsHandle, protocol int, groups ...uint) (*Ne
|
||||||
|
|
||||||
func (s *NetlinkSocket) Close() {
|
func (s *NetlinkSocket) Close() {
|
||||||
fd := int(atomic.SwapInt32(&s.fd, -1))
|
fd := int(atomic.SwapInt32(&s.fd, -1))
|
||||||
unix.Close(fd)
|
syscall.Close(fd)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *NetlinkSocket) GetFd() int {
|
func (s *NetlinkSocket) GetFd() int {
|
||||||
|
@ -604,7 +598,7 @@ func (s *NetlinkSocket) Send(request *NetlinkRequest) error {
|
||||||
if fd < 0 {
|
if fd < 0 {
|
||||||
return fmt.Errorf("Send called on a closed socket")
|
return fmt.Errorf("Send called on a closed socket")
|
||||||
}
|
}
|
||||||
if err := unix.Sendto(fd, request.Serialize(), 0, &s.lsa); err != nil {
|
if err := syscall.Sendto(fd, request.Serialize(), 0, &s.lsa); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
|
@ -615,12 +609,12 @@ func (s *NetlinkSocket) Receive() ([]syscall.NetlinkMessage, error) {
|
||||||
if fd < 0 {
|
if fd < 0 {
|
||||||
return nil, fmt.Errorf("Receive called on a closed socket")
|
return nil, fmt.Errorf("Receive called on a closed socket")
|
||||||
}
|
}
|
||||||
rb := make([]byte, unix.Getpagesize())
|
rb := make([]byte, syscall.Getpagesize())
|
||||||
nr, _, err := unix.Recvfrom(fd, rb, 0)
|
nr, _, err := syscall.Recvfrom(fd, rb, 0)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
if nr < unix.NLMSG_HDRLEN {
|
if nr < syscall.NLMSG_HDRLEN {
|
||||||
return nil, fmt.Errorf("Got short response from netlink")
|
return nil, fmt.Errorf("Got short response from netlink")
|
||||||
}
|
}
|
||||||
rb = rb[:nr]
|
rb = rb[:nr]
|
||||||
|
@ -628,27 +622,27 @@ func (s *NetlinkSocket) Receive() ([]syscall.NetlinkMessage, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetSendTimeout allows to set a send timeout on the socket
|
// SetSendTimeout allows to set a send timeout on the socket
|
||||||
func (s *NetlinkSocket) SetSendTimeout(timeout *unix.Timeval) error {
|
func (s *NetlinkSocket) SetSendTimeout(timeout *syscall.Timeval) error {
|
||||||
// Set a send timeout of SOCKET_SEND_TIMEOUT, this will allow the Send to periodically unblock and avoid that a routine
|
// Set a send timeout of SOCKET_SEND_TIMEOUT, this will allow the Send to periodically unblock and avoid that a routine
|
||||||
// remains stuck on a send on a closed fd
|
// remains stuck on a send on a closed fd
|
||||||
return unix.SetsockoptTimeval(int(s.fd), unix.SOL_SOCKET, unix.SO_SNDTIMEO, timeout)
|
return syscall.SetsockoptTimeval(int(s.fd), syscall.SOL_SOCKET, syscall.SO_SNDTIMEO, timeout)
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetReceiveTimeout allows to set a receive timeout on the socket
|
// SetReceiveTimeout allows to set a receive timeout on the socket
|
||||||
func (s *NetlinkSocket) SetReceiveTimeout(timeout *unix.Timeval) error {
|
func (s *NetlinkSocket) SetReceiveTimeout(timeout *syscall.Timeval) error {
|
||||||
// Set a read timeout of SOCKET_READ_TIMEOUT, this will allow the Read to periodically unblock and avoid that a routine
|
// Set a read timeout of SOCKET_READ_TIMEOUT, this will allow the Read to periodically unblock and avoid that a routine
|
||||||
// remains stuck on a recvmsg on a closed fd
|
// remains stuck on a recvmsg on a closed fd
|
||||||
return unix.SetsockoptTimeval(int(s.fd), unix.SOL_SOCKET, unix.SO_RCVTIMEO, timeout)
|
return syscall.SetsockoptTimeval(int(s.fd), syscall.SOL_SOCKET, syscall.SO_RCVTIMEO, timeout)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *NetlinkSocket) GetPid() (uint32, error) {
|
func (s *NetlinkSocket) GetPid() (uint32, error) {
|
||||||
fd := int(atomic.LoadInt32(&s.fd))
|
fd := int(atomic.LoadInt32(&s.fd))
|
||||||
lsa, err := unix.Getsockname(fd)
|
lsa, err := syscall.Getsockname(fd)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, err
|
return 0, err
|
||||||
}
|
}
|
||||||
switch v := lsa.(type) {
|
switch v := lsa.(type) {
|
||||||
case *unix.SockaddrNetlink:
|
case *syscall.SockaddrNetlink:
|
||||||
return v.Pid, nil
|
return v.Pid, nil
|
||||||
}
|
}
|
||||||
return 0, fmt.Errorf("Wrong socket type")
|
return 0, fmt.Errorf("Wrong socket type")
|
||||||
|
@ -703,24 +697,24 @@ func Uint64Attr(v uint64) []byte {
|
||||||
|
|
||||||
func ParseRouteAttr(b []byte) ([]syscall.NetlinkRouteAttr, error) {
|
func ParseRouteAttr(b []byte) ([]syscall.NetlinkRouteAttr, error) {
|
||||||
var attrs []syscall.NetlinkRouteAttr
|
var attrs []syscall.NetlinkRouteAttr
|
||||||
for len(b) >= unix.SizeofRtAttr {
|
for len(b) >= syscall.SizeofRtAttr {
|
||||||
a, vbuf, alen, err := netlinkRouteAttrAndValue(b)
|
a, vbuf, alen, err := netlinkRouteAttrAndValue(b)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
ra := syscall.NetlinkRouteAttr{Attr: syscall.RtAttr(*a), Value: vbuf[:int(a.Len)-unix.SizeofRtAttr]}
|
ra := syscall.NetlinkRouteAttr{Attr: *a, Value: vbuf[:int(a.Len)-syscall.SizeofRtAttr]}
|
||||||
attrs = append(attrs, ra)
|
attrs = append(attrs, ra)
|
||||||
b = b[alen:]
|
b = b[alen:]
|
||||||
}
|
}
|
||||||
return attrs, nil
|
return attrs, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func netlinkRouteAttrAndValue(b []byte) (*unix.RtAttr, []byte, int, error) {
|
func netlinkRouteAttrAndValue(b []byte) (*syscall.RtAttr, []byte, int, error) {
|
||||||
a := (*unix.RtAttr)(unsafe.Pointer(&b[0]))
|
a := (*syscall.RtAttr)(unsafe.Pointer(&b[0]))
|
||||||
if int(a.Len) < unix.SizeofRtAttr || int(a.Len) > len(b) {
|
if int(a.Len) < syscall.SizeofRtAttr || int(a.Len) > len(b) {
|
||||||
return nil, nil, 0, unix.EINVAL
|
return nil, nil, 0, syscall.EINVAL
|
||||||
}
|
}
|
||||||
return a, b[unix.SizeofRtAttr:], rtaAlignOf(int(a.Len)), nil
|
return a, b[syscall.SizeofRtAttr:], rtaAlignOf(int(a.Len)), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// SocketHandle contains the netlink socket and the associated
|
// SocketHandle contains the netlink socket and the associated
|
||||||
|
|
|
@ -1,66 +1,65 @@
|
||||||
package nl
|
package nl
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"syscall"
|
||||||
"unsafe"
|
"unsafe"
|
||||||
|
|
||||||
"golang.org/x/sys/unix"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type RtMsg struct {
|
type RtMsg struct {
|
||||||
unix.RtMsg
|
syscall.RtMsg
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewRtMsg() *RtMsg {
|
func NewRtMsg() *RtMsg {
|
||||||
return &RtMsg{
|
return &RtMsg{
|
||||||
RtMsg: unix.RtMsg{
|
RtMsg: syscall.RtMsg{
|
||||||
Table: unix.RT_TABLE_MAIN,
|
Table: syscall.RT_TABLE_MAIN,
|
||||||
Scope: unix.RT_SCOPE_UNIVERSE,
|
Scope: syscall.RT_SCOPE_UNIVERSE,
|
||||||
Protocol: unix.RTPROT_BOOT,
|
Protocol: syscall.RTPROT_BOOT,
|
||||||
Type: unix.RTN_UNICAST,
|
Type: syscall.RTN_UNICAST,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewRtDelMsg() *RtMsg {
|
func NewRtDelMsg() *RtMsg {
|
||||||
return &RtMsg{
|
return &RtMsg{
|
||||||
RtMsg: unix.RtMsg{
|
RtMsg: syscall.RtMsg{
|
||||||
Table: unix.RT_TABLE_MAIN,
|
Table: syscall.RT_TABLE_MAIN,
|
||||||
Scope: unix.RT_SCOPE_NOWHERE,
|
Scope: syscall.RT_SCOPE_NOWHERE,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (msg *RtMsg) Len() int {
|
func (msg *RtMsg) Len() int {
|
||||||
return unix.SizeofRtMsg
|
return syscall.SizeofRtMsg
|
||||||
}
|
}
|
||||||
|
|
||||||
func DeserializeRtMsg(b []byte) *RtMsg {
|
func DeserializeRtMsg(b []byte) *RtMsg {
|
||||||
return (*RtMsg)(unsafe.Pointer(&b[0:unix.SizeofRtMsg][0]))
|
return (*RtMsg)(unsafe.Pointer(&b[0:syscall.SizeofRtMsg][0]))
|
||||||
}
|
}
|
||||||
|
|
||||||
func (msg *RtMsg) Serialize() []byte {
|
func (msg *RtMsg) Serialize() []byte {
|
||||||
return (*(*[unix.SizeofRtMsg]byte)(unsafe.Pointer(msg)))[:]
|
return (*(*[syscall.SizeofRtMsg]byte)(unsafe.Pointer(msg)))[:]
|
||||||
}
|
}
|
||||||
|
|
||||||
type RtNexthop struct {
|
type RtNexthop struct {
|
||||||
unix.RtNexthop
|
syscall.RtNexthop
|
||||||
Children []NetlinkRequestData
|
Children []NetlinkRequestData
|
||||||
}
|
}
|
||||||
|
|
||||||
func DeserializeRtNexthop(b []byte) *RtNexthop {
|
func DeserializeRtNexthop(b []byte) *RtNexthop {
|
||||||
return (*RtNexthop)(unsafe.Pointer(&b[0:unix.SizeofRtNexthop][0]))
|
return (*RtNexthop)(unsafe.Pointer(&b[0:syscall.SizeofRtNexthop][0]))
|
||||||
}
|
}
|
||||||
|
|
||||||
func (msg *RtNexthop) Len() int {
|
func (msg *RtNexthop) Len() int {
|
||||||
if len(msg.Children) == 0 {
|
if len(msg.Children) == 0 {
|
||||||
return unix.SizeofRtNexthop
|
return syscall.SizeofRtNexthop
|
||||||
}
|
}
|
||||||
|
|
||||||
l := 0
|
l := 0
|
||||||
for _, child := range msg.Children {
|
for _, child := range msg.Children {
|
||||||
l += rtaAlignOf(child.Len())
|
l += rtaAlignOf(child.Len())
|
||||||
}
|
}
|
||||||
l += unix.SizeofRtNexthop
|
l += syscall.SizeofRtNexthop
|
||||||
return rtaAlignOf(l)
|
return rtaAlignOf(l)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -68,8 +67,8 @@ func (msg *RtNexthop) Serialize() []byte {
|
||||||
length := msg.Len()
|
length := msg.Len()
|
||||||
msg.RtNexthop.Len = uint16(length)
|
msg.RtNexthop.Len = uint16(length)
|
||||||
buf := make([]byte, length)
|
buf := make([]byte, length)
|
||||||
copy(buf, (*(*[unix.SizeofRtNexthop]byte)(unsafe.Pointer(msg)))[:])
|
copy(buf, (*(*[syscall.SizeofRtNexthop]byte)(unsafe.Pointer(msg)))[:])
|
||||||
next := rtaAlignOf(unix.SizeofRtNexthop)
|
next := rtaAlignOf(syscall.SizeofRtNexthop)
|
||||||
if len(msg.Children) > 0 {
|
if len(msg.Children) > 0 {
|
||||||
for _, child := range msg.Children {
|
for _, child := range msg.Children {
|
||||||
childBuf := child.Serialize()
|
childBuf := child.Serialize()
|
||||||
|
|
|
@ -1,111 +0,0 @@
|
||||||
package nl
|
|
||||||
|
|
||||||
import (
|
|
||||||
"errors"
|
|
||||||
"fmt"
|
|
||||||
"net"
|
|
||||||
)
|
|
||||||
|
|
||||||
type IPv6SrHdr struct {
|
|
||||||
nextHdr uint8
|
|
||||||
hdrLen uint8
|
|
||||||
routingType uint8
|
|
||||||
segmentsLeft uint8
|
|
||||||
firstSegment uint8
|
|
||||||
flags uint8
|
|
||||||
reserved uint16
|
|
||||||
|
|
||||||
Segments []net.IP
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s1 *IPv6SrHdr) Equal(s2 IPv6SrHdr) bool {
|
|
||||||
if len(s1.Segments) != len(s2.Segments) {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
for i := range s1.Segments {
|
|
||||||
if s1.Segments[i].Equal(s2.Segments[i]) != true {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return s1.nextHdr == s2.nextHdr &&
|
|
||||||
s1.hdrLen == s2.hdrLen &&
|
|
||||||
s1.routingType == s2.routingType &&
|
|
||||||
s1.segmentsLeft == s2.segmentsLeft &&
|
|
||||||
s1.firstSegment == s2.firstSegment &&
|
|
||||||
s1.flags == s2.flags
|
|
||||||
// reserved doesn't need to be identical.
|
|
||||||
}
|
|
||||||
|
|
||||||
// seg6 encap mode
|
|
||||||
const (
|
|
||||||
SEG6_IPTUN_MODE_INLINE = iota
|
|
||||||
SEG6_IPTUN_MODE_ENCAP
|
|
||||||
)
|
|
||||||
|
|
||||||
// number of nested RTATTR
|
|
||||||
// from include/uapi/linux/seg6_iptunnel.h
|
|
||||||
const (
|
|
||||||
SEG6_IPTUNNEL_UNSPEC = iota
|
|
||||||
SEG6_IPTUNNEL_SRH
|
|
||||||
__SEG6_IPTUNNEL_MAX
|
|
||||||
)
|
|
||||||
const (
|
|
||||||
SEG6_IPTUNNEL_MAX = __SEG6_IPTUNNEL_MAX - 1
|
|
||||||
)
|
|
||||||
|
|
||||||
func EncodeSEG6Encap(mode int, segments []net.IP) ([]byte, error) {
|
|
||||||
nsegs := len(segments) // nsegs: number of segments
|
|
||||||
if nsegs == 0 {
|
|
||||||
return nil, errors.New("EncodeSEG6Encap: No Segment in srh")
|
|
||||||
}
|
|
||||||
b := make([]byte, 12, 12+len(segments)*16)
|
|
||||||
native := NativeEndian()
|
|
||||||
native.PutUint32(b, uint32(mode))
|
|
||||||
b[4] = 0 // srh.nextHdr (0 when calling netlink)
|
|
||||||
b[5] = uint8(16 * nsegs >> 3) // srh.hdrLen (in 8-octets unit)
|
|
||||||
b[6] = IPV6_SRCRT_TYPE_4 // srh.routingType (assigned by IANA)
|
|
||||||
b[7] = uint8(nsegs - 1) // srh.segmentsLeft
|
|
||||||
b[8] = uint8(nsegs - 1) // srh.firstSegment
|
|
||||||
b[9] = 0 // srh.flags (SR6_FLAG1_HMAC for srh_hmac)
|
|
||||||
// srh.reserved: Defined as "Tag" in draft-ietf-6man-segment-routing-header-07
|
|
||||||
native.PutUint16(b[10:], 0) // srh.reserved
|
|
||||||
for _, netIP := range segments {
|
|
||||||
b = append(b, netIP...) // srh.Segments
|
|
||||||
}
|
|
||||||
return b, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func DecodeSEG6Encap(buf []byte) (int, []net.IP, error) {
|
|
||||||
native := NativeEndian()
|
|
||||||
mode := int(native.Uint32(buf))
|
|
||||||
srh := IPv6SrHdr{
|
|
||||||
nextHdr: buf[4],
|
|
||||||
hdrLen: buf[5],
|
|
||||||
routingType: buf[6],
|
|
||||||
segmentsLeft: buf[7],
|
|
||||||
firstSegment: buf[8],
|
|
||||||
flags: buf[9],
|
|
||||||
reserved: native.Uint16(buf[10:12]),
|
|
||||||
}
|
|
||||||
buf = buf[12:]
|
|
||||||
if len(buf)%16 != 0 {
|
|
||||||
err := fmt.Errorf("DecodeSEG6Encap: error parsing Segment List (buf len: %d)\n", len(buf))
|
|
||||||
return mode, nil, err
|
|
||||||
}
|
|
||||||
for len(buf) > 0 {
|
|
||||||
srh.Segments = append(srh.Segments, net.IP(buf[:16]))
|
|
||||||
buf = buf[16:]
|
|
||||||
}
|
|
||||||
return mode, srh.Segments, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Helper functions
|
|
||||||
func SEG6EncapModeString(mode int) string {
|
|
||||||
switch mode {
|
|
||||||
case SEG6_IPTUN_MODE_INLINE:
|
|
||||||
return "inline"
|
|
||||||
case SEG6_IPTUN_MODE_ENCAP:
|
|
||||||
return "encap"
|
|
||||||
}
|
|
||||||
return "unknown"
|
|
||||||
}
|
|
|
@ -65,14 +65,4 @@ const (
|
||||||
LWTUNNEL_ENCAP_IP
|
LWTUNNEL_ENCAP_IP
|
||||||
LWTUNNEL_ENCAP_ILA
|
LWTUNNEL_ENCAP_ILA
|
||||||
LWTUNNEL_ENCAP_IP6
|
LWTUNNEL_ENCAP_IP6
|
||||||
LWTUNNEL_ENCAP_SEG6
|
|
||||||
LWTUNNEL_ENCAP_BPF
|
|
||||||
)
|
|
||||||
|
|
||||||
// routing header types
|
|
||||||
const (
|
|
||||||
IPV6_SRCRT_STRICT = 0x01 // Deprecated; will be removed
|
|
||||||
IPV6_SRCRT_TYPE_0 = 0 // Deprecated; will be removed
|
|
||||||
IPV6_SRCRT_TYPE_2 = 2 // IPv6 type 2 Routing Header
|
|
||||||
IPV6_SRCRT_TYPE_4 = 4 // Segment Routing with IPv6
|
|
||||||
)
|
)
|
||||||
|
|
|
@ -5,7 +5,6 @@ import (
|
||||||
"syscall"
|
"syscall"
|
||||||
|
|
||||||
"github.com/vishvananda/netlink/nl"
|
"github.com/vishvananda/netlink/nl"
|
||||||
"golang.org/x/sys/unix"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func LinkGetProtinfo(link Link) (Protinfo, error) {
|
func LinkGetProtinfo(link Link) (Protinfo, error) {
|
||||||
|
@ -16,10 +15,10 @@ func (h *Handle) LinkGetProtinfo(link Link) (Protinfo, error) {
|
||||||
base := link.Attrs()
|
base := link.Attrs()
|
||||||
h.ensureIndex(base)
|
h.ensureIndex(base)
|
||||||
var pi Protinfo
|
var pi Protinfo
|
||||||
req := h.newNetlinkRequest(unix.RTM_GETLINK, unix.NLM_F_DUMP)
|
req := h.newNetlinkRequest(syscall.RTM_GETLINK, syscall.NLM_F_DUMP)
|
||||||
msg := nl.NewIfInfomsg(unix.AF_BRIDGE)
|
msg := nl.NewIfInfomsg(syscall.AF_BRIDGE)
|
||||||
req.AddData(msg)
|
req.AddData(msg)
|
||||||
msgs, err := req.Execute(unix.NETLINK_ROUTE, 0)
|
msgs, err := req.Execute(syscall.NETLINK_ROUTE, 0)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return pi, err
|
return pi, err
|
||||||
}
|
}
|
||||||
|
@ -34,7 +33,7 @@ func (h *Handle) LinkGetProtinfo(link Link) (Protinfo, error) {
|
||||||
return pi, err
|
return pi, err
|
||||||
}
|
}
|
||||||
for _, attr := range attrs {
|
for _, attr := range attrs {
|
||||||
if attr.Attr.Type != unix.IFLA_PROTINFO|unix.NLA_F_NESTED {
|
if attr.Attr.Type != syscall.IFLA_PROTINFO|syscall.NLA_F_NESTED {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
infos, err := nl.ParseRouteAttr(attr.Value)
|
infos, err := nl.ParseRouteAttr(attr.Value)
|
||||||
|
|
|
@ -8,7 +8,6 @@ import (
|
||||||
"syscall"
|
"syscall"
|
||||||
|
|
||||||
"github.com/vishvananda/netlink/nl"
|
"github.com/vishvananda/netlink/nl"
|
||||||
"golang.org/x/sys/unix"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// NOTE function is here because it uses other linux functions
|
// NOTE function is here because it uses other linux functions
|
||||||
|
@ -85,7 +84,7 @@ func QdiscDel(qdisc Qdisc) error {
|
||||||
// QdiscDel will delete a qdisc from the system.
|
// QdiscDel will delete a qdisc from the system.
|
||||||
// Equivalent to: `tc qdisc del $qdisc`
|
// Equivalent to: `tc qdisc del $qdisc`
|
||||||
func (h *Handle) QdiscDel(qdisc Qdisc) error {
|
func (h *Handle) QdiscDel(qdisc Qdisc) error {
|
||||||
return h.qdiscModify(unix.RTM_DELQDISC, 0, qdisc)
|
return h.qdiscModify(syscall.RTM_DELQDISC, 0, qdisc)
|
||||||
}
|
}
|
||||||
|
|
||||||
// QdiscChange will change a qdisc in place
|
// QdiscChange will change a qdisc in place
|
||||||
|
@ -99,7 +98,7 @@ func QdiscChange(qdisc Qdisc) error {
|
||||||
// Equivalent to: `tc qdisc change $qdisc`
|
// Equivalent to: `tc qdisc change $qdisc`
|
||||||
// The parent and handle MUST NOT be changed.
|
// The parent and handle MUST NOT be changed.
|
||||||
func (h *Handle) QdiscChange(qdisc Qdisc) error {
|
func (h *Handle) QdiscChange(qdisc Qdisc) error {
|
||||||
return h.qdiscModify(unix.RTM_NEWQDISC, 0, qdisc)
|
return h.qdiscModify(syscall.RTM_NEWQDISC, 0, qdisc)
|
||||||
}
|
}
|
||||||
|
|
||||||
// QdiscReplace will replace a qdisc to the system.
|
// QdiscReplace will replace a qdisc to the system.
|
||||||
|
@ -114,8 +113,8 @@ func QdiscReplace(qdisc Qdisc) error {
|
||||||
// The handle MUST change.
|
// The handle MUST change.
|
||||||
func (h *Handle) QdiscReplace(qdisc Qdisc) error {
|
func (h *Handle) QdiscReplace(qdisc Qdisc) error {
|
||||||
return h.qdiscModify(
|
return h.qdiscModify(
|
||||||
unix.RTM_NEWQDISC,
|
syscall.RTM_NEWQDISC,
|
||||||
unix.NLM_F_CREATE|unix.NLM_F_REPLACE,
|
syscall.NLM_F_CREATE|syscall.NLM_F_REPLACE,
|
||||||
qdisc)
|
qdisc)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -129,13 +128,13 @@ func QdiscAdd(qdisc Qdisc) error {
|
||||||
// Equivalent to: `tc qdisc add $qdisc`
|
// Equivalent to: `tc qdisc add $qdisc`
|
||||||
func (h *Handle) QdiscAdd(qdisc Qdisc) error {
|
func (h *Handle) QdiscAdd(qdisc Qdisc) error {
|
||||||
return h.qdiscModify(
|
return h.qdiscModify(
|
||||||
unix.RTM_NEWQDISC,
|
syscall.RTM_NEWQDISC,
|
||||||
unix.NLM_F_CREATE|unix.NLM_F_EXCL,
|
syscall.NLM_F_CREATE|syscall.NLM_F_EXCL,
|
||||||
qdisc)
|
qdisc)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *Handle) qdiscModify(cmd, flags int, qdisc Qdisc) error {
|
func (h *Handle) qdiscModify(cmd, flags int, qdisc Qdisc) error {
|
||||||
req := h.newNetlinkRequest(cmd, flags|unix.NLM_F_ACK)
|
req := h.newNetlinkRequest(cmd, flags|syscall.NLM_F_ACK)
|
||||||
base := qdisc.Attrs()
|
base := qdisc.Attrs()
|
||||||
msg := &nl.TcMsg{
|
msg := &nl.TcMsg{
|
||||||
Family: nl.FAMILY_ALL,
|
Family: nl.FAMILY_ALL,
|
||||||
|
@ -146,13 +145,13 @@ func (h *Handle) qdiscModify(cmd, flags int, qdisc Qdisc) error {
|
||||||
req.AddData(msg)
|
req.AddData(msg)
|
||||||
|
|
||||||
// When deleting don't bother building the rest of the netlink payload
|
// When deleting don't bother building the rest of the netlink payload
|
||||||
if cmd != unix.RTM_DELQDISC {
|
if cmd != syscall.RTM_DELQDISC {
|
||||||
if err := qdiscPayload(req, qdisc); err != nil {
|
if err := qdiscPayload(req, qdisc); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_, err := req.Execute(unix.NETLINK_ROUTE, 0)
|
_, err := req.Execute(syscall.NETLINK_ROUTE, 0)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -249,7 +248,7 @@ func QdiscList(link Link) ([]Qdisc, error) {
|
||||||
// Equivalent to: `tc qdisc show`.
|
// Equivalent to: `tc qdisc show`.
|
||||||
// The list can be filtered by link.
|
// The list can be filtered by link.
|
||||||
func (h *Handle) QdiscList(link Link) ([]Qdisc, error) {
|
func (h *Handle) QdiscList(link Link) ([]Qdisc, error) {
|
||||||
req := h.newNetlinkRequest(unix.RTM_GETQDISC, unix.NLM_F_DUMP)
|
req := h.newNetlinkRequest(syscall.RTM_GETQDISC, syscall.NLM_F_DUMP)
|
||||||
index := int32(0)
|
index := int32(0)
|
||||||
if link != nil {
|
if link != nil {
|
||||||
base := link.Attrs()
|
base := link.Attrs()
|
||||||
|
@ -262,7 +261,7 @@ func (h *Handle) QdiscList(link Link) ([]Qdisc, error) {
|
||||||
}
|
}
|
||||||
req.AddData(msg)
|
req.AddData(msg)
|
||||||
|
|
||||||
msgs, err := req.Execute(unix.NETLINK_ROUTE, unix.RTM_NEWQDISC)
|
msgs, err := req.Execute(syscall.NETLINK_ROUTE, syscall.RTM_NEWQDISC)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
|
@ -45,8 +45,6 @@ type Route struct {
|
||||||
MPLSDst *int
|
MPLSDst *int
|
||||||
NewDst Destination
|
NewDst Destination
|
||||||
Encap Encap
|
Encap Encap
|
||||||
MTU int
|
|
||||||
AdvMSS int
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r Route) String() string {
|
func (r Route) String() string {
|
||||||
|
|
|
@ -8,17 +8,16 @@ import (
|
||||||
|
|
||||||
"github.com/vishvananda/netlink/nl"
|
"github.com/vishvananda/netlink/nl"
|
||||||
"github.com/vishvananda/netns"
|
"github.com/vishvananda/netns"
|
||||||
"golang.org/x/sys/unix"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// RtAttr is shared so it is in netlink_linux.go
|
// RtAttr is shared so it is in netlink_linux.go
|
||||||
|
|
||||||
const (
|
const (
|
||||||
SCOPE_UNIVERSE Scope = unix.RT_SCOPE_UNIVERSE
|
SCOPE_UNIVERSE Scope = syscall.RT_SCOPE_UNIVERSE
|
||||||
SCOPE_SITE Scope = unix.RT_SCOPE_SITE
|
SCOPE_SITE Scope = syscall.RT_SCOPE_SITE
|
||||||
SCOPE_LINK Scope = unix.RT_SCOPE_LINK
|
SCOPE_LINK Scope = syscall.RT_SCOPE_LINK
|
||||||
SCOPE_HOST Scope = unix.RT_SCOPE_HOST
|
SCOPE_HOST Scope = syscall.RT_SCOPE_HOST
|
||||||
SCOPE_NOWHERE Scope = unix.RT_SCOPE_NOWHERE
|
SCOPE_NOWHERE Scope = syscall.RT_SCOPE_NOWHERE
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
@ -35,8 +34,8 @@ const (
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
FLAG_ONLINK NextHopFlag = unix.RTNH_F_ONLINK
|
FLAG_ONLINK NextHopFlag = syscall.RTNH_F_ONLINK
|
||||||
FLAG_PERVASIVE NextHopFlag = unix.RTNH_F_PERVASIVE
|
FLAG_PERVASIVE NextHopFlag = syscall.RTNH_F_PERVASIVE
|
||||||
)
|
)
|
||||||
|
|
||||||
var testFlags = []flagString{
|
var testFlags = []flagString{
|
||||||
|
@ -125,17 +124,17 @@ func (e *MPLSEncap) Type() int {
|
||||||
|
|
||||||
func (e *MPLSEncap) Decode(buf []byte) error {
|
func (e *MPLSEncap) Decode(buf []byte) error {
|
||||||
if len(buf) < 4 {
|
if len(buf) < 4 {
|
||||||
return fmt.Errorf("lack of bytes")
|
return fmt.Errorf("Lack of bytes")
|
||||||
}
|
}
|
||||||
native := nl.NativeEndian()
|
native := nl.NativeEndian()
|
||||||
l := native.Uint16(buf)
|
l := native.Uint16(buf)
|
||||||
if len(buf) < int(l) {
|
if len(buf) < int(l) {
|
||||||
return fmt.Errorf("lack of bytes")
|
return fmt.Errorf("Lack of bytes")
|
||||||
}
|
}
|
||||||
buf = buf[:l]
|
buf = buf[:l]
|
||||||
typ := native.Uint16(buf[2:])
|
typ := native.Uint16(buf[2:])
|
||||||
if typ != nl.MPLS_IPTUNNEL_DST {
|
if typ != nl.MPLS_IPTUNNEL_DST {
|
||||||
return fmt.Errorf("unknown MPLS Encap Type: %d", typ)
|
return fmt.Errorf("Unknown MPLS Encap Type: %d", typ)
|
||||||
}
|
}
|
||||||
e.Labels = nl.DecodeMPLSStack(buf[4:])
|
e.Labels = nl.DecodeMPLSStack(buf[4:])
|
||||||
return nil
|
return nil
|
||||||
|
@ -186,79 +185,6 @@ func (e *MPLSEncap) Equal(x Encap) bool {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
// SEG6 definitions
|
|
||||||
type SEG6Encap struct {
|
|
||||||
Mode int
|
|
||||||
Segments []net.IP
|
|
||||||
}
|
|
||||||
|
|
||||||
func (e *SEG6Encap) Type() int {
|
|
||||||
return nl.LWTUNNEL_ENCAP_SEG6
|
|
||||||
}
|
|
||||||
func (e *SEG6Encap) Decode(buf []byte) error {
|
|
||||||
if len(buf) < 4 {
|
|
||||||
return fmt.Errorf("lack of bytes")
|
|
||||||
}
|
|
||||||
native := nl.NativeEndian()
|
|
||||||
// Get Length(l) & Type(typ) : 2 + 2 bytes
|
|
||||||
l := native.Uint16(buf)
|
|
||||||
if len(buf) < int(l) {
|
|
||||||
return fmt.Errorf("lack of bytes")
|
|
||||||
}
|
|
||||||
buf = buf[:l] // make sure buf size upper limit is Length
|
|
||||||
typ := native.Uint16(buf[2:])
|
|
||||||
if typ != nl.SEG6_IPTUNNEL_SRH {
|
|
||||||
return fmt.Errorf("unknown SEG6 Type: %d", typ)
|
|
||||||
}
|
|
||||||
|
|
||||||
var err error
|
|
||||||
e.Mode, e.Segments, err = nl.DecodeSEG6Encap(buf[4:])
|
|
||||||
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
func (e *SEG6Encap) Encode() ([]byte, error) {
|
|
||||||
s, err := nl.EncodeSEG6Encap(e.Mode, e.Segments)
|
|
||||||
native := nl.NativeEndian()
|
|
||||||
hdr := make([]byte, 4)
|
|
||||||
native.PutUint16(hdr, uint16(len(s)+4))
|
|
||||||
native.PutUint16(hdr[2:], nl.SEG6_IPTUNNEL_SRH)
|
|
||||||
return append(hdr, s...), err
|
|
||||||
}
|
|
||||||
func (e *SEG6Encap) String() string {
|
|
||||||
segs := make([]string, 0, len(e.Segments))
|
|
||||||
// append segment backwards (from n to 0) since seg#0 is the last segment.
|
|
||||||
for i := len(e.Segments); i > 0; i-- {
|
|
||||||
segs = append(segs, fmt.Sprintf("%s", e.Segments[i-1]))
|
|
||||||
}
|
|
||||||
str := fmt.Sprintf("mode %s segs %d [ %s ]", nl.SEG6EncapModeString(e.Mode),
|
|
||||||
len(e.Segments), strings.Join(segs, " "))
|
|
||||||
return str
|
|
||||||
}
|
|
||||||
func (e *SEG6Encap) Equal(x Encap) bool {
|
|
||||||
o, ok := x.(*SEG6Encap)
|
|
||||||
if !ok {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
if e == o {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
if e == nil || o == nil {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
if e.Mode != o.Mode {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
if len(e.Segments) != len(o.Segments) {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
for i := range e.Segments {
|
|
||||||
if !e.Segments[i].Equal(o.Segments[i]) {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
// RouteAdd will add a route to the system.
|
// RouteAdd will add a route to the system.
|
||||||
// Equivalent to: `ip route add $route`
|
// Equivalent to: `ip route add $route`
|
||||||
func RouteAdd(route *Route) error {
|
func RouteAdd(route *Route) error {
|
||||||
|
@ -268,8 +194,8 @@ func RouteAdd(route *Route) error {
|
||||||
// RouteAdd will add a route to the system.
|
// RouteAdd will add a route to the system.
|
||||||
// Equivalent to: `ip route add $route`
|
// Equivalent to: `ip route add $route`
|
||||||
func (h *Handle) RouteAdd(route *Route) error {
|
func (h *Handle) RouteAdd(route *Route) error {
|
||||||
flags := unix.NLM_F_CREATE | unix.NLM_F_EXCL | unix.NLM_F_ACK
|
flags := syscall.NLM_F_CREATE | syscall.NLM_F_EXCL | syscall.NLM_F_ACK
|
||||||
req := h.newNetlinkRequest(unix.RTM_NEWROUTE, flags)
|
req := h.newNetlinkRequest(syscall.RTM_NEWROUTE, flags)
|
||||||
return h.routeHandle(route, req, nl.NewRtMsg())
|
return h.routeHandle(route, req, nl.NewRtMsg())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -282,8 +208,8 @@ func RouteReplace(route *Route) error {
|
||||||
// RouteReplace will add a route to the system.
|
// RouteReplace will add a route to the system.
|
||||||
// Equivalent to: `ip route replace $route`
|
// Equivalent to: `ip route replace $route`
|
||||||
func (h *Handle) RouteReplace(route *Route) error {
|
func (h *Handle) RouteReplace(route *Route) error {
|
||||||
flags := unix.NLM_F_CREATE | unix.NLM_F_REPLACE | unix.NLM_F_ACK
|
flags := syscall.NLM_F_CREATE | syscall.NLM_F_REPLACE | syscall.NLM_F_ACK
|
||||||
req := h.newNetlinkRequest(unix.RTM_NEWROUTE, flags)
|
req := h.newNetlinkRequest(syscall.RTM_NEWROUTE, flags)
|
||||||
return h.routeHandle(route, req, nl.NewRtMsg())
|
return h.routeHandle(route, req, nl.NewRtMsg())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -296,7 +222,7 @@ func RouteDel(route *Route) error {
|
||||||
// RouteDel will delete a route from the system.
|
// RouteDel will delete a route from the system.
|
||||||
// Equivalent to: `ip route del $route`
|
// Equivalent to: `ip route del $route`
|
||||||
func (h *Handle) RouteDel(route *Route) error {
|
func (h *Handle) RouteDel(route *Route) error {
|
||||||
req := h.newNetlinkRequest(unix.RTM_DELROUTE, unix.NLM_F_ACK)
|
req := h.newNetlinkRequest(syscall.RTM_DELROUTE, syscall.NLM_F_ACK)
|
||||||
return h.routeHandle(route, req, nl.NewRtDelMsg())
|
return h.routeHandle(route, req, nl.NewRtDelMsg())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -319,12 +245,12 @@ func (h *Handle) routeHandle(route *Route, req *nl.NetlinkRequest, msg *nl.RtMsg
|
||||||
} else {
|
} else {
|
||||||
dstData = route.Dst.IP.To16()
|
dstData = route.Dst.IP.To16()
|
||||||
}
|
}
|
||||||
rtAttrs = append(rtAttrs, nl.NewRtAttr(unix.RTA_DST, dstData))
|
rtAttrs = append(rtAttrs, nl.NewRtAttr(syscall.RTA_DST, dstData))
|
||||||
} else if route.MPLSDst != nil {
|
} else if route.MPLSDst != nil {
|
||||||
family = nl.FAMILY_MPLS
|
family = nl.FAMILY_MPLS
|
||||||
msg.Dst_len = uint8(20)
|
msg.Dst_len = uint8(20)
|
||||||
msg.Type = unix.RTN_UNICAST
|
msg.Type = syscall.RTN_UNICAST
|
||||||
rtAttrs = append(rtAttrs, nl.NewRtAttr(unix.RTA_DST, nl.EncodeMPLSStack(*route.MPLSDst)))
|
rtAttrs = append(rtAttrs, nl.NewRtAttr(syscall.RTA_DST, nl.EncodeMPLSStack(*route.MPLSDst)))
|
||||||
}
|
}
|
||||||
|
|
||||||
if route.NewDst != nil {
|
if route.NewDst != nil {
|
||||||
|
@ -362,7 +288,7 @@ func (h *Handle) routeHandle(route *Route, req *nl.NetlinkRequest, msg *nl.RtMsg
|
||||||
srcData = route.Src.To16()
|
srcData = route.Src.To16()
|
||||||
}
|
}
|
||||||
// The commonly used src ip for routes is actually PREFSRC
|
// The commonly used src ip for routes is actually PREFSRC
|
||||||
rtAttrs = append(rtAttrs, nl.NewRtAttr(unix.RTA_PREFSRC, srcData))
|
rtAttrs = append(rtAttrs, nl.NewRtAttr(syscall.RTA_PREFSRC, srcData))
|
||||||
}
|
}
|
||||||
|
|
||||||
if route.Gw != nil {
|
if route.Gw != nil {
|
||||||
|
@ -377,14 +303,14 @@ func (h *Handle) routeHandle(route *Route, req *nl.NetlinkRequest, msg *nl.RtMsg
|
||||||
} else {
|
} else {
|
||||||
gwData = route.Gw.To16()
|
gwData = route.Gw.To16()
|
||||||
}
|
}
|
||||||
rtAttrs = append(rtAttrs, nl.NewRtAttr(unix.RTA_GATEWAY, gwData))
|
rtAttrs = append(rtAttrs, nl.NewRtAttr(syscall.RTA_GATEWAY, gwData))
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(route.MultiPath) > 0 {
|
if len(route.MultiPath) > 0 {
|
||||||
buf := []byte{}
|
buf := []byte{}
|
||||||
for _, nh := range route.MultiPath {
|
for _, nh := range route.MultiPath {
|
||||||
rtnh := &nl.RtNexthop{
|
rtnh := &nl.RtNexthop{
|
||||||
RtNexthop: unix.RtNexthop{
|
RtNexthop: syscall.RtNexthop{
|
||||||
Hops: uint8(nh.Hops),
|
Hops: uint8(nh.Hops),
|
||||||
Ifindex: int32(nh.LinkIndex),
|
Ifindex: int32(nh.LinkIndex),
|
||||||
Flags: uint8(nh.Flags),
|
Flags: uint8(nh.Flags),
|
||||||
|
@ -397,9 +323,9 @@ func (h *Handle) routeHandle(route *Route, req *nl.NetlinkRequest, msg *nl.RtMsg
|
||||||
return fmt.Errorf("gateway, source, and destination ip are not the same IP family")
|
return fmt.Errorf("gateway, source, and destination ip are not the same IP family")
|
||||||
}
|
}
|
||||||
if gwFamily == FAMILY_V4 {
|
if gwFamily == FAMILY_V4 {
|
||||||
children = append(children, nl.NewRtAttr(unix.RTA_GATEWAY, []byte(nh.Gw.To4())))
|
children = append(children, nl.NewRtAttr(syscall.RTA_GATEWAY, []byte(nh.Gw.To4())))
|
||||||
} else {
|
} else {
|
||||||
children = append(children, nl.NewRtAttr(unix.RTA_GATEWAY, []byte(nh.Gw.To16())))
|
children = append(children, nl.NewRtAttr(syscall.RTA_GATEWAY, []byte(nh.Gw.To16())))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if nh.NewDst != nil {
|
if nh.NewDst != nil {
|
||||||
|
@ -425,15 +351,15 @@ func (h *Handle) routeHandle(route *Route, req *nl.NetlinkRequest, msg *nl.RtMsg
|
||||||
rtnh.Children = children
|
rtnh.Children = children
|
||||||
buf = append(buf, rtnh.Serialize()...)
|
buf = append(buf, rtnh.Serialize()...)
|
||||||
}
|
}
|
||||||
rtAttrs = append(rtAttrs, nl.NewRtAttr(unix.RTA_MULTIPATH, buf))
|
rtAttrs = append(rtAttrs, nl.NewRtAttr(syscall.RTA_MULTIPATH, buf))
|
||||||
}
|
}
|
||||||
|
|
||||||
if route.Table > 0 {
|
if route.Table > 0 {
|
||||||
if route.Table >= 256 {
|
if route.Table >= 256 {
|
||||||
msg.Table = unix.RT_TABLE_UNSPEC
|
msg.Table = syscall.RT_TABLE_UNSPEC
|
||||||
b := make([]byte, 4)
|
b := make([]byte, 4)
|
||||||
native.PutUint32(b, uint32(route.Table))
|
native.PutUint32(b, uint32(route.Table))
|
||||||
rtAttrs = append(rtAttrs, nl.NewRtAttr(unix.RTA_TABLE, b))
|
rtAttrs = append(rtAttrs, nl.NewRtAttr(syscall.RTA_TABLE, b))
|
||||||
} else {
|
} else {
|
||||||
msg.Table = uint8(route.Table)
|
msg.Table = uint8(route.Table)
|
||||||
}
|
}
|
||||||
|
@ -442,7 +368,7 @@ func (h *Handle) routeHandle(route *Route, req *nl.NetlinkRequest, msg *nl.RtMsg
|
||||||
if route.Priority > 0 {
|
if route.Priority > 0 {
|
||||||
b := make([]byte, 4)
|
b := make([]byte, 4)
|
||||||
native.PutUint32(b, uint32(route.Priority))
|
native.PutUint32(b, uint32(route.Priority))
|
||||||
rtAttrs = append(rtAttrs, nl.NewRtAttr(unix.RTA_PRIORITY, b))
|
rtAttrs = append(rtAttrs, nl.NewRtAttr(syscall.RTA_PRIORITY, b))
|
||||||
}
|
}
|
||||||
if route.Tos > 0 {
|
if route.Tos > 0 {
|
||||||
msg.Tos = uint8(route.Tos)
|
msg.Tos = uint8(route.Tos)
|
||||||
|
@ -454,25 +380,6 @@ func (h *Handle) routeHandle(route *Route, req *nl.NetlinkRequest, msg *nl.RtMsg
|
||||||
msg.Type = uint8(route.Type)
|
msg.Type = uint8(route.Type)
|
||||||
}
|
}
|
||||||
|
|
||||||
var metrics []*nl.RtAttr
|
|
||||||
// TODO: support other rta_metric values
|
|
||||||
if route.MTU > 0 {
|
|
||||||
b := nl.Uint32Attr(uint32(route.MTU))
|
|
||||||
metrics = append(metrics, nl.NewRtAttr(unix.RTAX_MTU, b))
|
|
||||||
}
|
|
||||||
if route.AdvMSS > 0 {
|
|
||||||
b := nl.Uint32Attr(uint32(route.AdvMSS))
|
|
||||||
metrics = append(metrics, nl.NewRtAttr(unix.RTAX_ADVMSS, b))
|
|
||||||
}
|
|
||||||
|
|
||||||
if metrics != nil {
|
|
||||||
attr := nl.NewRtAttr(unix.RTA_METRICS, nil)
|
|
||||||
for _, metric := range metrics {
|
|
||||||
attr.AddChild(metric)
|
|
||||||
}
|
|
||||||
rtAttrs = append(rtAttrs, attr)
|
|
||||||
}
|
|
||||||
|
|
||||||
msg.Flags = uint32(route.Flags)
|
msg.Flags = uint32(route.Flags)
|
||||||
msg.Scope = uint8(route.Scope)
|
msg.Scope = uint8(route.Scope)
|
||||||
msg.Family = uint8(family)
|
msg.Family = uint8(family)
|
||||||
|
@ -487,9 +394,9 @@ func (h *Handle) routeHandle(route *Route, req *nl.NetlinkRequest, msg *nl.RtMsg
|
||||||
)
|
)
|
||||||
native.PutUint32(b, uint32(route.LinkIndex))
|
native.PutUint32(b, uint32(route.LinkIndex))
|
||||||
|
|
||||||
req.AddData(nl.NewRtAttr(unix.RTA_OIF, b))
|
req.AddData(nl.NewRtAttr(syscall.RTA_OIF, b))
|
||||||
|
|
||||||
_, err := req.Execute(unix.NETLINK_ROUTE, 0)
|
_, err := req.Execute(syscall.NETLINK_ROUTE, 0)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -522,11 +429,11 @@ func RouteListFiltered(family int, filter *Route, filterMask uint64) ([]Route, e
|
||||||
// RouteListFiltered gets a list of routes in the system filtered with specified rules.
|
// RouteListFiltered gets a list of routes in the system filtered with specified rules.
|
||||||
// All rules must be defined in RouteFilter struct
|
// All rules must be defined in RouteFilter struct
|
||||||
func (h *Handle) RouteListFiltered(family int, filter *Route, filterMask uint64) ([]Route, error) {
|
func (h *Handle) RouteListFiltered(family int, filter *Route, filterMask uint64) ([]Route, error) {
|
||||||
req := h.newNetlinkRequest(unix.RTM_GETROUTE, unix.NLM_F_DUMP)
|
req := h.newNetlinkRequest(syscall.RTM_GETROUTE, syscall.NLM_F_DUMP)
|
||||||
infmsg := nl.NewIfInfomsg(family)
|
infmsg := nl.NewIfInfomsg(family)
|
||||||
req.AddData(infmsg)
|
req.AddData(infmsg)
|
||||||
|
|
||||||
msgs, err := req.Execute(unix.NETLINK_ROUTE, unix.RTM_NEWROUTE)
|
msgs, err := req.Execute(syscall.NETLINK_ROUTE, syscall.RTM_NEWROUTE)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -534,11 +441,11 @@ func (h *Handle) RouteListFiltered(family int, filter *Route, filterMask uint64)
|
||||||
var res []Route
|
var res []Route
|
||||||
for _, m := range msgs {
|
for _, m := range msgs {
|
||||||
msg := nl.DeserializeRtMsg(m)
|
msg := nl.DeserializeRtMsg(m)
|
||||||
if msg.Flags&unix.RTM_F_CLONED != 0 {
|
if msg.Flags&syscall.RTM_F_CLONED != 0 {
|
||||||
// Ignore cloned routes
|
// Ignore cloned routes
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if msg.Table != unix.RT_TABLE_MAIN {
|
if msg.Table != syscall.RT_TABLE_MAIN {
|
||||||
if filter == nil || filter != nil && filterMask&RT_FILTER_TABLE == 0 {
|
if filter == nil || filter != nil && filterMask&RT_FILTER_TABLE == 0 {
|
||||||
// Ignore non-main tables
|
// Ignore non-main tables
|
||||||
continue
|
continue
|
||||||
|
@ -550,7 +457,7 @@ func (h *Handle) RouteListFiltered(family int, filter *Route, filterMask uint64)
|
||||||
}
|
}
|
||||||
if filter != nil {
|
if filter != nil {
|
||||||
switch {
|
switch {
|
||||||
case filterMask&RT_FILTER_TABLE != 0 && filter.Table != unix.RT_TABLE_UNSPEC && route.Table != filter.Table:
|
case filterMask&RT_FILTER_TABLE != 0 && filter.Table != syscall.RT_TABLE_UNSPEC && route.Table != filter.Table:
|
||||||
continue
|
continue
|
||||||
case filterMask&RT_FILTER_PROTOCOL != 0 && route.Protocol != filter.Protocol:
|
case filterMask&RT_FILTER_PROTOCOL != 0 && route.Protocol != filter.Protocol:
|
||||||
continue
|
continue
|
||||||
|
@ -601,11 +508,11 @@ func deserializeRoute(m []byte) (Route, error) {
|
||||||
var encap, encapType syscall.NetlinkRouteAttr
|
var encap, encapType syscall.NetlinkRouteAttr
|
||||||
for _, attr := range attrs {
|
for _, attr := range attrs {
|
||||||
switch attr.Attr.Type {
|
switch attr.Attr.Type {
|
||||||
case unix.RTA_GATEWAY:
|
case syscall.RTA_GATEWAY:
|
||||||
route.Gw = net.IP(attr.Value)
|
route.Gw = net.IP(attr.Value)
|
||||||
case unix.RTA_PREFSRC:
|
case syscall.RTA_PREFSRC:
|
||||||
route.Src = net.IP(attr.Value)
|
route.Src = net.IP(attr.Value)
|
||||||
case unix.RTA_DST:
|
case syscall.RTA_DST:
|
||||||
if msg.Family == nl.FAMILY_MPLS {
|
if msg.Family == nl.FAMILY_MPLS {
|
||||||
stack := nl.DecodeMPLSStack(attr.Value)
|
stack := nl.DecodeMPLSStack(attr.Value)
|
||||||
if len(stack) == 0 || len(stack) > 1 {
|
if len(stack) == 0 || len(stack) > 1 {
|
||||||
|
@ -618,36 +525,36 @@ func deserializeRoute(m []byte) (Route, error) {
|
||||||
Mask: net.CIDRMask(int(msg.Dst_len), 8*len(attr.Value)),
|
Mask: net.CIDRMask(int(msg.Dst_len), 8*len(attr.Value)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
case unix.RTA_OIF:
|
case syscall.RTA_OIF:
|
||||||
route.LinkIndex = int(native.Uint32(attr.Value[0:4]))
|
route.LinkIndex = int(native.Uint32(attr.Value[0:4]))
|
||||||
case unix.RTA_IIF:
|
case syscall.RTA_IIF:
|
||||||
route.ILinkIndex = int(native.Uint32(attr.Value[0:4]))
|
route.ILinkIndex = int(native.Uint32(attr.Value[0:4]))
|
||||||
case unix.RTA_PRIORITY:
|
case syscall.RTA_PRIORITY:
|
||||||
route.Priority = int(native.Uint32(attr.Value[0:4]))
|
route.Priority = int(native.Uint32(attr.Value[0:4]))
|
||||||
case unix.RTA_TABLE:
|
case syscall.RTA_TABLE:
|
||||||
route.Table = int(native.Uint32(attr.Value[0:4]))
|
route.Table = int(native.Uint32(attr.Value[0:4]))
|
||||||
case unix.RTA_MULTIPATH:
|
case syscall.RTA_MULTIPATH:
|
||||||
parseRtNexthop := func(value []byte) (*NexthopInfo, []byte, error) {
|
parseRtNexthop := func(value []byte) (*NexthopInfo, []byte, error) {
|
||||||
if len(value) < unix.SizeofRtNexthop {
|
if len(value) < syscall.SizeofRtNexthop {
|
||||||
return nil, nil, fmt.Errorf("lack of bytes")
|
return nil, nil, fmt.Errorf("Lack of bytes")
|
||||||
}
|
}
|
||||||
nh := nl.DeserializeRtNexthop(value)
|
nh := nl.DeserializeRtNexthop(value)
|
||||||
if len(value) < int(nh.RtNexthop.Len) {
|
if len(value) < int(nh.RtNexthop.Len) {
|
||||||
return nil, nil, fmt.Errorf("lack of bytes")
|
return nil, nil, fmt.Errorf("Lack of bytes")
|
||||||
}
|
}
|
||||||
info := &NexthopInfo{
|
info := &NexthopInfo{
|
||||||
LinkIndex: int(nh.RtNexthop.Ifindex),
|
LinkIndex: int(nh.RtNexthop.Ifindex),
|
||||||
Hops: int(nh.RtNexthop.Hops),
|
Hops: int(nh.RtNexthop.Hops),
|
||||||
Flags: int(nh.RtNexthop.Flags),
|
Flags: int(nh.RtNexthop.Flags),
|
||||||
}
|
}
|
||||||
attrs, err := nl.ParseRouteAttr(value[unix.SizeofRtNexthop:int(nh.RtNexthop.Len)])
|
attrs, err := nl.ParseRouteAttr(value[syscall.SizeofRtNexthop:int(nh.RtNexthop.Len)])
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, err
|
return nil, nil, err
|
||||||
}
|
}
|
||||||
var encap, encapType syscall.NetlinkRouteAttr
|
var encap, encapType syscall.NetlinkRouteAttr
|
||||||
for _, attr := range attrs {
|
for _, attr := range attrs {
|
||||||
switch attr.Attr.Type {
|
switch attr.Attr.Type {
|
||||||
case unix.RTA_GATEWAY:
|
case syscall.RTA_GATEWAY:
|
||||||
info.Gw = net.IP(attr.Value)
|
info.Gw = net.IP(attr.Value)
|
||||||
case nl.RTA_NEWDST:
|
case nl.RTA_NEWDST:
|
||||||
var d Destination
|
var d Destination
|
||||||
|
@ -704,19 +611,6 @@ func deserializeRoute(m []byte) (Route, error) {
|
||||||
encapType = attr
|
encapType = attr
|
||||||
case nl.RTA_ENCAP:
|
case nl.RTA_ENCAP:
|
||||||
encap = attr
|
encap = attr
|
||||||
case unix.RTA_METRICS:
|
|
||||||
metrics, err := nl.ParseRouteAttr(attr.Value)
|
|
||||||
if err != nil {
|
|
||||||
return route, err
|
|
||||||
}
|
|
||||||
for _, metric := range metrics {
|
|
||||||
switch metric.Attr.Type {
|
|
||||||
case unix.RTAX_MTU:
|
|
||||||
route.MTU = int(native.Uint32(metric.Value[0:4]))
|
|
||||||
case unix.RTAX_ADVMSS:
|
|
||||||
route.AdvMSS = int(native.Uint32(metric.Value[0:4]))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -729,11 +623,6 @@ func deserializeRoute(m []byte) (Route, error) {
|
||||||
if err := e.Decode(encap.Value); err != nil {
|
if err := e.Decode(encap.Value); err != nil {
|
||||||
return route, err
|
return route, err
|
||||||
}
|
}
|
||||||
case nl.LWTUNNEL_ENCAP_SEG6:
|
|
||||||
e = &SEG6Encap{}
|
|
||||||
if err := e.Decode(encap.Value); err != nil {
|
|
||||||
return route, err
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
route.Encap = e
|
route.Encap = e
|
||||||
}
|
}
|
||||||
|
@ -750,7 +639,7 @@ func RouteGet(destination net.IP) ([]Route, error) {
|
||||||
// RouteGet gets a route to a specific destination from the host system.
|
// RouteGet gets a route to a specific destination from the host system.
|
||||||
// Equivalent to: 'ip route get'.
|
// Equivalent to: 'ip route get'.
|
||||||
func (h *Handle) RouteGet(destination net.IP) ([]Route, error) {
|
func (h *Handle) RouteGet(destination net.IP) ([]Route, error) {
|
||||||
req := h.newNetlinkRequest(unix.RTM_GETROUTE, unix.NLM_F_REQUEST)
|
req := h.newNetlinkRequest(syscall.RTM_GETROUTE, syscall.NLM_F_REQUEST)
|
||||||
family := nl.GetIPFamily(destination)
|
family := nl.GetIPFamily(destination)
|
||||||
var destinationData []byte
|
var destinationData []byte
|
||||||
var bitlen uint8
|
var bitlen uint8
|
||||||
|
@ -766,10 +655,10 @@ func (h *Handle) RouteGet(destination net.IP) ([]Route, error) {
|
||||||
msg.Dst_len = bitlen
|
msg.Dst_len = bitlen
|
||||||
req.AddData(msg)
|
req.AddData(msg)
|
||||||
|
|
||||||
rtaDst := nl.NewRtAttr(unix.RTA_DST, destinationData)
|
rtaDst := nl.NewRtAttr(syscall.RTA_DST, destinationData)
|
||||||
req.AddData(rtaDst)
|
req.AddData(rtaDst)
|
||||||
|
|
||||||
msgs, err := req.Execute(unix.NETLINK_ROUTE, unix.RTM_NEWROUTE)
|
msgs, err := req.Execute(syscall.NETLINK_ROUTE, syscall.RTM_NEWROUTE)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -817,7 +706,7 @@ func RouteSubscribeWithOptions(ch chan<- RouteUpdate, done <-chan struct{}, opti
|
||||||
}
|
}
|
||||||
|
|
||||||
func routeSubscribeAt(newNs, curNs netns.NsHandle, ch chan<- RouteUpdate, done <-chan struct{}, cberr func(error)) error {
|
func routeSubscribeAt(newNs, curNs netns.NsHandle, ch chan<- RouteUpdate, done <-chan struct{}, cberr func(error)) error {
|
||||||
s, err := nl.SubscribeAt(newNs, curNs, unix.NETLINK_ROUTE, unix.RTNLGRP_IPV4_ROUTE, unix.RTNLGRP_IPV6_ROUTE)
|
s, err := nl.SubscribeAt(newNs, curNs, syscall.NETLINK_ROUTE, syscall.RTNLGRP_IPV4_ROUTE, syscall.RTNLGRP_IPV6_ROUTE)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,7 +21,6 @@ type Rule struct {
|
||||||
OifName string
|
OifName string
|
||||||
SuppressIfgroup int
|
SuppressIfgroup int
|
||||||
SuppressPrefixlen int
|
SuppressPrefixlen int
|
||||||
Invert bool
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r Rule) String() string {
|
func (r Rule) String() string {
|
||||||
|
|
|
@ -3,13 +3,11 @@ package netlink
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"net"
|
"net"
|
||||||
|
"syscall"
|
||||||
|
|
||||||
"github.com/vishvananda/netlink/nl"
|
"github.com/vishvananda/netlink/nl"
|
||||||
"golang.org/x/sys/unix"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
const FibRuleInvert = 0x2
|
|
||||||
|
|
||||||
// RuleAdd adds a rule to the system.
|
// RuleAdd adds a rule to the system.
|
||||||
// Equivalent to: ip rule add
|
// Equivalent to: ip rule add
|
||||||
func RuleAdd(rule *Rule) error {
|
func RuleAdd(rule *Rule) error {
|
||||||
|
@ -19,7 +17,7 @@ func RuleAdd(rule *Rule) error {
|
||||||
// RuleAdd adds a rule to the system.
|
// RuleAdd adds a rule to the system.
|
||||||
// Equivalent to: ip rule add
|
// Equivalent to: ip rule add
|
||||||
func (h *Handle) RuleAdd(rule *Rule) error {
|
func (h *Handle) RuleAdd(rule *Rule) error {
|
||||||
req := h.newNetlinkRequest(unix.RTM_NEWRULE, unix.NLM_F_CREATE|unix.NLM_F_EXCL|unix.NLM_F_ACK)
|
req := h.newNetlinkRequest(syscall.RTM_NEWRULE, syscall.NLM_F_CREATE|syscall.NLM_F_EXCL|syscall.NLM_F_ACK)
|
||||||
return ruleHandle(rule, req)
|
return ruleHandle(rule, req)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -32,31 +30,18 @@ func RuleDel(rule *Rule) error {
|
||||||
// RuleDel deletes a rule from the system.
|
// RuleDel deletes a rule from the system.
|
||||||
// Equivalent to: ip rule del
|
// Equivalent to: ip rule del
|
||||||
func (h *Handle) RuleDel(rule *Rule) error {
|
func (h *Handle) RuleDel(rule *Rule) error {
|
||||||
req := h.newNetlinkRequest(unix.RTM_DELRULE, unix.NLM_F_ACK)
|
req := h.newNetlinkRequest(syscall.RTM_DELRULE, syscall.NLM_F_CREATE|syscall.NLM_F_EXCL|syscall.NLM_F_ACK)
|
||||||
return ruleHandle(rule, req)
|
return ruleHandle(rule, req)
|
||||||
}
|
}
|
||||||
|
|
||||||
func ruleHandle(rule *Rule, req *nl.NetlinkRequest) error {
|
func ruleHandle(rule *Rule, req *nl.NetlinkRequest) error {
|
||||||
msg := nl.NewRtMsg()
|
msg := nl.NewRtMsg()
|
||||||
msg.Family = unix.AF_INET
|
msg.Family = syscall.AF_INET
|
||||||
msg.Protocol = unix.RTPROT_BOOT
|
|
||||||
msg.Scope = unix.RT_SCOPE_UNIVERSE
|
|
||||||
msg.Table = unix.RT_TABLE_UNSPEC
|
|
||||||
msg.Type = unix.RTN_UNSPEC
|
|
||||||
if req.NlMsghdr.Flags&unix.NLM_F_CREATE > 0 {
|
|
||||||
msg.Type = unix.RTN_UNICAST
|
|
||||||
}
|
|
||||||
if rule.Invert {
|
|
||||||
msg.Flags |= FibRuleInvert
|
|
||||||
}
|
|
||||||
if rule.Family != 0 {
|
if rule.Family != 0 {
|
||||||
msg.Family = uint8(rule.Family)
|
msg.Family = uint8(rule.Family)
|
||||||
}
|
}
|
||||||
if rule.Table >= 0 && rule.Table < 256 {
|
|
||||||
msg.Table = uint8(rule.Table)
|
|
||||||
}
|
|
||||||
|
|
||||||
var dstFamily uint8
|
var dstFamily uint8
|
||||||
|
|
||||||
var rtAttrs []*nl.RtAttr
|
var rtAttrs []*nl.RtAttr
|
||||||
if rule.Dst != nil && rule.Dst.IP != nil {
|
if rule.Dst != nil && rule.Dst.IP != nil {
|
||||||
dstLen, _ := rule.Dst.Mask.Size()
|
dstLen, _ := rule.Dst.Mask.Size()
|
||||||
|
@ -64,12 +49,12 @@ func ruleHandle(rule *Rule, req *nl.NetlinkRequest) error {
|
||||||
msg.Family = uint8(nl.GetIPFamily(rule.Dst.IP))
|
msg.Family = uint8(nl.GetIPFamily(rule.Dst.IP))
|
||||||
dstFamily = msg.Family
|
dstFamily = msg.Family
|
||||||
var dstData []byte
|
var dstData []byte
|
||||||
if msg.Family == unix.AF_INET {
|
if msg.Family == syscall.AF_INET {
|
||||||
dstData = rule.Dst.IP.To4()
|
dstData = rule.Dst.IP.To4()
|
||||||
} else {
|
} else {
|
||||||
dstData = rule.Dst.IP.To16()
|
dstData = rule.Dst.IP.To16()
|
||||||
}
|
}
|
||||||
rtAttrs = append(rtAttrs, nl.NewRtAttr(unix.RTA_DST, dstData))
|
rtAttrs = append(rtAttrs, nl.NewRtAttr(syscall.RTA_DST, dstData))
|
||||||
}
|
}
|
||||||
|
|
||||||
if rule.Src != nil && rule.Src.IP != nil {
|
if rule.Src != nil && rule.Src.IP != nil {
|
||||||
|
@ -80,12 +65,19 @@ func ruleHandle(rule *Rule, req *nl.NetlinkRequest) error {
|
||||||
srcLen, _ := rule.Src.Mask.Size()
|
srcLen, _ := rule.Src.Mask.Size()
|
||||||
msg.Src_len = uint8(srcLen)
|
msg.Src_len = uint8(srcLen)
|
||||||
var srcData []byte
|
var srcData []byte
|
||||||
if msg.Family == unix.AF_INET {
|
if msg.Family == syscall.AF_INET {
|
||||||
srcData = rule.Src.IP.To4()
|
srcData = rule.Src.IP.To4()
|
||||||
} else {
|
} else {
|
||||||
srcData = rule.Src.IP.To16()
|
srcData = rule.Src.IP.To16()
|
||||||
}
|
}
|
||||||
rtAttrs = append(rtAttrs, nl.NewRtAttr(unix.RTA_SRC, srcData))
|
rtAttrs = append(rtAttrs, nl.NewRtAttr(syscall.RTA_SRC, srcData))
|
||||||
|
}
|
||||||
|
|
||||||
|
if rule.Table >= 0 {
|
||||||
|
msg.Table = uint8(rule.Table)
|
||||||
|
if rule.Table >= 256 {
|
||||||
|
msg.Table = syscall.RT_TABLE_UNSPEC
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
req.AddData(msg)
|
req.AddData(msg)
|
||||||
|
@ -150,7 +142,7 @@ func ruleHandle(rule *Rule, req *nl.NetlinkRequest) error {
|
||||||
req.AddData(nl.NewRtAttr(nl.FRA_GOTO, b))
|
req.AddData(nl.NewRtAttr(nl.FRA_GOTO, b))
|
||||||
}
|
}
|
||||||
|
|
||||||
_, err := req.Execute(unix.NETLINK_ROUTE, 0)
|
_, err := req.Execute(syscall.NETLINK_ROUTE, 0)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -163,11 +155,11 @@ func RuleList(family int) ([]Rule, error) {
|
||||||
// RuleList lists rules in the system.
|
// RuleList lists rules in the system.
|
||||||
// Equivalent to: ip rule list
|
// Equivalent to: ip rule list
|
||||||
func (h *Handle) RuleList(family int) ([]Rule, error) {
|
func (h *Handle) RuleList(family int) ([]Rule, error) {
|
||||||
req := h.newNetlinkRequest(unix.RTM_GETRULE, unix.NLM_F_DUMP|unix.NLM_F_REQUEST)
|
req := h.newNetlinkRequest(syscall.RTM_GETRULE, syscall.NLM_F_DUMP|syscall.NLM_F_REQUEST)
|
||||||
msg := nl.NewIfInfomsg(family)
|
msg := nl.NewIfInfomsg(family)
|
||||||
req.AddData(msg)
|
req.AddData(msg)
|
||||||
|
|
||||||
msgs, err := req.Execute(unix.NETLINK_ROUTE, unix.RTM_NEWRULE)
|
msgs, err := req.Execute(syscall.NETLINK_ROUTE, syscall.RTM_NEWRULE)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -183,11 +175,9 @@ func (h *Handle) RuleList(family int) ([]Rule, error) {
|
||||||
|
|
||||||
rule := NewRule()
|
rule := NewRule()
|
||||||
|
|
||||||
rule.Invert = msg.Flags&FibRuleInvert > 0
|
|
||||||
|
|
||||||
for j := range attrs {
|
for j := range attrs {
|
||||||
switch attrs[j].Attr.Type {
|
switch attrs[j].Attr.Type {
|
||||||
case unix.RTA_TABLE:
|
case syscall.RTA_TABLE:
|
||||||
rule.Table = int(native.Uint32(attrs[j].Value[0:4]))
|
rule.Table = int(native.Uint32(attrs[j].Value[0:4]))
|
||||||
case nl.FRA_SRC:
|
case nl.FRA_SRC:
|
||||||
rule.Src = &net.IPNet{
|
rule.Src = &net.IPNet{
|
||||||
|
|
|
@ -4,9 +4,9 @@ import (
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"net"
|
"net"
|
||||||
|
"syscall"
|
||||||
|
|
||||||
"github.com/vishvananda/netlink/nl"
|
"github.com/vishvananda/netlink/nl"
|
||||||
"golang.org/x/sys/unix"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
@ -123,15 +123,15 @@ func SocketGet(local, remote net.Addr) (*Socket, error) {
|
||||||
return nil, ErrNotImplemented
|
return nil, ErrNotImplemented
|
||||||
}
|
}
|
||||||
|
|
||||||
s, err := nl.Subscribe(unix.NETLINK_INET_DIAG)
|
s, err := nl.Subscribe(syscall.NETLINK_INET_DIAG)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
defer s.Close()
|
defer s.Close()
|
||||||
req := nl.NewNetlinkRequest(nl.SOCK_DIAG_BY_FAMILY, 0)
|
req := nl.NewNetlinkRequest(nl.SOCK_DIAG_BY_FAMILY, 0)
|
||||||
req.AddData(&socketRequest{
|
req.AddData(&socketRequest{
|
||||||
Family: unix.AF_INET,
|
Family: syscall.AF_INET,
|
||||||
Protocol: unix.IPPROTO_TCP,
|
Protocol: syscall.IPPROTO_TCP,
|
||||||
ID: SocketID{
|
ID: SocketID{
|
||||||
SourcePort: uint16(localTCP.Port),
|
SourcePort: uint16(localTCP.Port),
|
||||||
DestinationPort: uint16(remoteTCP.Port),
|
DestinationPort: uint16(remoteTCP.Port),
|
||||||
|
|
|
@ -2,20 +2,19 @@ package netlink
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"syscall"
|
||||||
"golang.org/x/sys/unix"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// Proto is an enum representing an ipsec protocol.
|
// Proto is an enum representing an ipsec protocol.
|
||||||
type Proto uint8
|
type Proto uint8
|
||||||
|
|
||||||
const (
|
const (
|
||||||
XFRM_PROTO_ROUTE2 Proto = unix.IPPROTO_ROUTING
|
XFRM_PROTO_ROUTE2 Proto = syscall.IPPROTO_ROUTING
|
||||||
XFRM_PROTO_ESP Proto = unix.IPPROTO_ESP
|
XFRM_PROTO_ESP Proto = syscall.IPPROTO_ESP
|
||||||
XFRM_PROTO_AH Proto = unix.IPPROTO_AH
|
XFRM_PROTO_AH Proto = syscall.IPPROTO_AH
|
||||||
XFRM_PROTO_HAO Proto = unix.IPPROTO_DSTOPTS
|
XFRM_PROTO_HAO Proto = syscall.IPPROTO_DSTOPTS
|
||||||
XFRM_PROTO_COMP Proto = 0x6c // NOTE not defined on darwin
|
XFRM_PROTO_COMP Proto = 0x6c // NOTE not defined on darwin
|
||||||
XFRM_PROTO_IPSEC_ANY Proto = unix.IPPROTO_RAW
|
XFRM_PROTO_IPSEC_ANY Proto = syscall.IPPROTO_RAW
|
||||||
)
|
)
|
||||||
|
|
||||||
func (p Proto) String() string {
|
func (p Proto) String() string {
|
||||||
|
|
|
@ -2,10 +2,11 @@ package netlink
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"syscall"
|
||||||
|
|
||||||
|
"github.com/vishvananda/netns"
|
||||||
|
|
||||||
"github.com/vishvananda/netlink/nl"
|
"github.com/vishvananda/netlink/nl"
|
||||||
"github.com/vishvananda/netns"
|
|
||||||
"golang.org/x/sys/unix"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type XfrmMsg interface {
|
type XfrmMsg interface {
|
||||||
|
@ -38,7 +39,7 @@ func XfrmMonitor(ch chan<- XfrmMsg, done <-chan struct{}, errorChan chan<- error
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
s, err := nl.SubscribeAt(netns.None(), netns.None(), unix.NETLINK_XFRM, groups...)
|
s, err := nl.SubscribeAt(netns.None(), netns.None(), syscall.NETLINK_XFRM, groups...)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,8 +1,9 @@
|
||||||
package netlink
|
package netlink
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"syscall"
|
||||||
|
|
||||||
"github.com/vishvananda/netlink/nl"
|
"github.com/vishvananda/netlink/nl"
|
||||||
"golang.org/x/sys/unix"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func selFromPolicy(sel *nl.XfrmSelector, policy *XfrmPolicy) {
|
func selFromPolicy(sel *nl.XfrmSelector, policy *XfrmPolicy) {
|
||||||
|
@ -54,7 +55,7 @@ func (h *Handle) XfrmPolicyUpdate(policy *XfrmPolicy) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *Handle) xfrmPolicyAddOrUpdate(policy *XfrmPolicy, nlProto int) error {
|
func (h *Handle) xfrmPolicyAddOrUpdate(policy *XfrmPolicy, nlProto int) error {
|
||||||
req := h.newNetlinkRequest(nlProto, unix.NLM_F_CREATE|unix.NLM_F_EXCL|unix.NLM_F_ACK)
|
req := h.newNetlinkRequest(nlProto, syscall.NLM_F_CREATE|syscall.NLM_F_EXCL|syscall.NLM_F_ACK)
|
||||||
|
|
||||||
msg := &nl.XfrmUserpolicyInfo{}
|
msg := &nl.XfrmUserpolicyInfo{}
|
||||||
selFromPolicy(&msg.Sel, policy)
|
selFromPolicy(&msg.Sel, policy)
|
||||||
|
@ -90,7 +91,7 @@ func (h *Handle) xfrmPolicyAddOrUpdate(policy *XfrmPolicy, nlProto int) error {
|
||||||
req.AddData(out)
|
req.AddData(out)
|
||||||
}
|
}
|
||||||
|
|
||||||
_, err := req.Execute(unix.NETLINK_XFRM, 0)
|
_, err := req.Execute(syscall.NETLINK_XFRM, 0)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -120,12 +121,12 @@ func XfrmPolicyList(family int) ([]XfrmPolicy, error) {
|
||||||
// Equivalent to: `ip xfrm policy show`.
|
// Equivalent to: `ip xfrm policy show`.
|
||||||
// The list can be filtered by ip family.
|
// The list can be filtered by ip family.
|
||||||
func (h *Handle) XfrmPolicyList(family int) ([]XfrmPolicy, error) {
|
func (h *Handle) XfrmPolicyList(family int) ([]XfrmPolicy, error) {
|
||||||
req := h.newNetlinkRequest(nl.XFRM_MSG_GETPOLICY, unix.NLM_F_DUMP)
|
req := h.newNetlinkRequest(nl.XFRM_MSG_GETPOLICY, syscall.NLM_F_DUMP)
|
||||||
|
|
||||||
msg := nl.NewIfInfomsg(family)
|
msg := nl.NewIfInfomsg(family)
|
||||||
req.AddData(msg)
|
req.AddData(msg)
|
||||||
|
|
||||||
msgs, err := req.Execute(unix.NETLINK_XFRM, nl.XFRM_MSG_NEWPOLICY)
|
msgs, err := req.Execute(syscall.NETLINK_XFRM, nl.XFRM_MSG_NEWPOLICY)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -164,13 +165,13 @@ func XfrmPolicyFlush() error {
|
||||||
// XfrmPolicyFlush will flush the policies on the system.
|
// XfrmPolicyFlush will flush the policies on the system.
|
||||||
// Equivalent to: `ip xfrm policy flush`
|
// Equivalent to: `ip xfrm policy flush`
|
||||||
func (h *Handle) XfrmPolicyFlush() error {
|
func (h *Handle) XfrmPolicyFlush() error {
|
||||||
req := h.newNetlinkRequest(nl.XFRM_MSG_FLUSHPOLICY, unix.NLM_F_ACK)
|
req := h.newNetlinkRequest(nl.XFRM_MSG_FLUSHPOLICY, syscall.NLM_F_ACK)
|
||||||
_, err := req.Execute(unix.NETLINK_XFRM, 0)
|
_, err := req.Execute(syscall.NETLINK_XFRM, 0)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *Handle) xfrmPolicyGetOrDelete(policy *XfrmPolicy, nlProto int) (*XfrmPolicy, error) {
|
func (h *Handle) xfrmPolicyGetOrDelete(policy *XfrmPolicy, nlProto int) (*XfrmPolicy, error) {
|
||||||
req := h.newNetlinkRequest(nlProto, unix.NLM_F_ACK)
|
req := h.newNetlinkRequest(nlProto, syscall.NLM_F_ACK)
|
||||||
|
|
||||||
msg := &nl.XfrmUserpolicyId{}
|
msg := &nl.XfrmUserpolicyId{}
|
||||||
selFromPolicy(&msg.Sel, policy)
|
selFromPolicy(&msg.Sel, policy)
|
||||||
|
@ -188,7 +189,7 @@ func (h *Handle) xfrmPolicyGetOrDelete(policy *XfrmPolicy, nlProto int) (*XfrmPo
|
||||||
resType = 0
|
resType = 0
|
||||||
}
|
}
|
||||||
|
|
||||||
msgs, err := req.Execute(unix.NETLINK_XFRM, uint16(resType))
|
msgs, err := req.Execute(syscall.NETLINK_XFRM, uint16(resType))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,7 +3,6 @@ package netlink
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"net"
|
"net"
|
||||||
"time"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// XfrmStateAlgo represents the algorithm to use for the ipsec encryption.
|
// XfrmStateAlgo represents the algorithm to use for the ipsec encryption.
|
||||||
|
@ -68,19 +67,6 @@ type XfrmStateLimits struct {
|
||||||
TimeUseHard uint64
|
TimeUseHard uint64
|
||||||
}
|
}
|
||||||
|
|
||||||
// XfrmStateStats represents the current number of bytes/packets
|
|
||||||
// processed by this State, the State's installation and first use
|
|
||||||
// time and the replay window counters.
|
|
||||||
type XfrmStateStats struct {
|
|
||||||
ReplayWindow uint32
|
|
||||||
Replay uint32
|
|
||||||
Failed uint32
|
|
||||||
Bytes uint64
|
|
||||||
Packets uint64
|
|
||||||
AddTime uint64
|
|
||||||
UseTime uint64
|
|
||||||
}
|
|
||||||
|
|
||||||
// XfrmState represents the state of an ipsec policy. It optionally
|
// XfrmState represents the state of an ipsec policy. It optionally
|
||||||
// contains an XfrmStateAlgo for encryption and one for authentication.
|
// contains an XfrmStateAlgo for encryption and one for authentication.
|
||||||
type XfrmState struct {
|
type XfrmState struct {
|
||||||
|
@ -92,7 +78,6 @@ type XfrmState struct {
|
||||||
Reqid int
|
Reqid int
|
||||||
ReplayWindow int
|
ReplayWindow int
|
||||||
Limits XfrmStateLimits
|
Limits XfrmStateLimits
|
||||||
Statistics XfrmStateStats
|
|
||||||
Mark *XfrmMark
|
Mark *XfrmMark
|
||||||
Auth *XfrmStateAlgo
|
Auth *XfrmStateAlgo
|
||||||
Crypt *XfrmStateAlgo
|
Crypt *XfrmStateAlgo
|
||||||
|
@ -109,16 +94,10 @@ func (sa XfrmState) Print(stats bool) string {
|
||||||
if !stats {
|
if !stats {
|
||||||
return sa.String()
|
return sa.String()
|
||||||
}
|
}
|
||||||
at := time.Unix(int64(sa.Statistics.AddTime), 0).Format(time.UnixDate)
|
|
||||||
ut := "-"
|
return fmt.Sprintf("%s, ByteSoft: %s, ByteHard: %s, PacketSoft: %s, PacketHard: %s, TimeSoft: %d, TimeHard: %d, TimeUseSoft: %d, TimeUseHard: %d",
|
||||||
if sa.Statistics.UseTime > 0 {
|
|
||||||
ut = time.Unix(int64(sa.Statistics.UseTime), 0).Format(time.UnixDate)
|
|
||||||
}
|
|
||||||
return fmt.Sprintf("%s, ByteSoft: %s, ByteHard: %s, PacketSoft: %s, PacketHard: %s, TimeSoft: %d, TimeHard: %d, TimeUseSoft: %d, TimeUseHard: %d, Bytes: %d, Packets: %d, "+
|
|
||||||
"AddTime: %s, UseTime: %s, ReplayWindow: %d, Replay: %d, Failed: %d",
|
|
||||||
sa.String(), printLimit(sa.Limits.ByteSoft), printLimit(sa.Limits.ByteHard), printLimit(sa.Limits.PacketSoft), printLimit(sa.Limits.PacketHard),
|
sa.String(), printLimit(sa.Limits.ByteSoft), printLimit(sa.Limits.ByteHard), printLimit(sa.Limits.PacketSoft), printLimit(sa.Limits.PacketHard),
|
||||||
sa.Limits.TimeSoft, sa.Limits.TimeHard, sa.Limits.TimeUseSoft, sa.Limits.TimeUseHard, sa.Statistics.Bytes, sa.Statistics.Packets, at, ut,
|
sa.Limits.TimeSoft, sa.Limits.TimeHard, sa.Limits.TimeUseSoft, sa.Limits.TimeUseHard)
|
||||||
sa.Statistics.ReplayWindow, sa.Statistics.Replay, sa.Statistics.Failed)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func printLimit(lmt uint64) string {
|
func printLimit(lmt uint64) string {
|
||||||
|
|
|
@ -2,10 +2,10 @@ package netlink
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"syscall"
|
||||||
"unsafe"
|
"unsafe"
|
||||||
|
|
||||||
"github.com/vishvananda/netlink/nl"
|
"github.com/vishvananda/netlink/nl"
|
||||||
"golang.org/x/sys/unix"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func writeStateAlgo(a *XfrmStateAlgo) []byte {
|
func writeStateAlgo(a *XfrmStateAlgo) []byte {
|
||||||
|
@ -111,7 +111,7 @@ func (h *Handle) xfrmStateAddOrUpdate(state *XfrmState, nlProto int) error {
|
||||||
if state.Spi == 0 {
|
if state.Spi == 0 {
|
||||||
return fmt.Errorf("Spi must be set when adding xfrm state.")
|
return fmt.Errorf("Spi must be set when adding xfrm state.")
|
||||||
}
|
}
|
||||||
req := h.newNetlinkRequest(nlProto, unix.NLM_F_CREATE|unix.NLM_F_EXCL|unix.NLM_F_ACK)
|
req := h.newNetlinkRequest(nlProto, syscall.NLM_F_CREATE|syscall.NLM_F_EXCL|syscall.NLM_F_ACK)
|
||||||
|
|
||||||
msg := xfrmUsersaInfoFromXfrmState(state)
|
msg := xfrmUsersaInfoFromXfrmState(state)
|
||||||
|
|
||||||
|
@ -157,13 +157,13 @@ func (h *Handle) xfrmStateAddOrUpdate(state *XfrmState, nlProto int) error {
|
||||||
req.AddData(out)
|
req.AddData(out)
|
||||||
}
|
}
|
||||||
|
|
||||||
_, err := req.Execute(unix.NETLINK_XFRM, 0)
|
_, err := req.Execute(syscall.NETLINK_XFRM, 0)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *Handle) xfrmStateAllocSpi(state *XfrmState) (*XfrmState, error) {
|
func (h *Handle) xfrmStateAllocSpi(state *XfrmState) (*XfrmState, error) {
|
||||||
req := h.newNetlinkRequest(nl.XFRM_MSG_ALLOCSPI,
|
req := h.newNetlinkRequest(nl.XFRM_MSG_ALLOCSPI,
|
||||||
unix.NLM_F_CREATE|unix.NLM_F_EXCL|unix.NLM_F_ACK)
|
syscall.NLM_F_CREATE|syscall.NLM_F_EXCL|syscall.NLM_F_ACK)
|
||||||
|
|
||||||
msg := &nl.XfrmUserSpiInfo{}
|
msg := &nl.XfrmUserSpiInfo{}
|
||||||
msg.XfrmUsersaInfo = *(xfrmUsersaInfoFromXfrmState(state))
|
msg.XfrmUsersaInfo = *(xfrmUsersaInfoFromXfrmState(state))
|
||||||
|
@ -177,7 +177,7 @@ func (h *Handle) xfrmStateAllocSpi(state *XfrmState) (*XfrmState, error) {
|
||||||
req.AddData(out)
|
req.AddData(out)
|
||||||
}
|
}
|
||||||
|
|
||||||
msgs, err := req.Execute(unix.NETLINK_XFRM, 0)
|
msgs, err := req.Execute(syscall.NETLINK_XFRM, 0)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -216,9 +216,9 @@ func XfrmStateList(family int) ([]XfrmState, error) {
|
||||||
// Equivalent to: `ip xfrm state show`.
|
// Equivalent to: `ip xfrm state show`.
|
||||||
// The list can be filtered by ip family.
|
// The list can be filtered by ip family.
|
||||||
func (h *Handle) XfrmStateList(family int) ([]XfrmState, error) {
|
func (h *Handle) XfrmStateList(family int) ([]XfrmState, error) {
|
||||||
req := h.newNetlinkRequest(nl.XFRM_MSG_GETSA, unix.NLM_F_DUMP)
|
req := h.newNetlinkRequest(nl.XFRM_MSG_GETSA, syscall.NLM_F_DUMP)
|
||||||
|
|
||||||
msgs, err := req.Execute(unix.NETLINK_XFRM, nl.XFRM_MSG_NEWSA)
|
msgs, err := req.Execute(syscall.NETLINK_XFRM, nl.XFRM_MSG_NEWSA)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -255,7 +255,7 @@ func (h *Handle) XfrmStateGet(state *XfrmState) (*XfrmState, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *Handle) xfrmStateGetOrDelete(state *XfrmState, nlProto int) (*XfrmState, error) {
|
func (h *Handle) xfrmStateGetOrDelete(state *XfrmState, nlProto int) (*XfrmState, error) {
|
||||||
req := h.newNetlinkRequest(nlProto, unix.NLM_F_ACK)
|
req := h.newNetlinkRequest(nlProto, syscall.NLM_F_ACK)
|
||||||
|
|
||||||
msg := &nl.XfrmUsersaId{}
|
msg := &nl.XfrmUsersaId{}
|
||||||
msg.Family = uint16(nl.GetIPFamily(state.Dst))
|
msg.Family = uint16(nl.GetIPFamily(state.Dst))
|
||||||
|
@ -278,7 +278,7 @@ func (h *Handle) xfrmStateGetOrDelete(state *XfrmState, nlProto int) (*XfrmState
|
||||||
resType = 0
|
resType = 0
|
||||||
}
|
}
|
||||||
|
|
||||||
msgs, err := req.Execute(unix.NETLINK_XFRM, uint16(resType))
|
msgs, err := req.Execute(syscall.NETLINK_XFRM, uint16(resType))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -308,7 +308,6 @@ func xfrmStateFromXfrmUsersaInfo(msg *nl.XfrmUsersaInfo) *XfrmState {
|
||||||
state.Reqid = int(msg.Reqid)
|
state.Reqid = int(msg.Reqid)
|
||||||
state.ReplayWindow = int(msg.ReplayWindow)
|
state.ReplayWindow = int(msg.ReplayWindow)
|
||||||
lftToLimits(&msg.Lft, &state.Limits)
|
lftToLimits(&msg.Lft, &state.Limits)
|
||||||
curToStats(&msg.Curlft, &msg.Stats, &state.Statistics)
|
|
||||||
|
|
||||||
return &state
|
return &state
|
||||||
}
|
}
|
||||||
|
@ -387,11 +386,11 @@ func XfrmStateFlush(proto Proto) error {
|
||||||
// proto = 0 means any transformation protocols
|
// proto = 0 means any transformation protocols
|
||||||
// Equivalent to: `ip xfrm state flush [ proto XFRM-PROTO ]`
|
// Equivalent to: `ip xfrm state flush [ proto XFRM-PROTO ]`
|
||||||
func (h *Handle) XfrmStateFlush(proto Proto) error {
|
func (h *Handle) XfrmStateFlush(proto Proto) error {
|
||||||
req := h.newNetlinkRequest(nl.XFRM_MSG_FLUSHSA, unix.NLM_F_ACK)
|
req := h.newNetlinkRequest(nl.XFRM_MSG_FLUSHSA, syscall.NLM_F_ACK)
|
||||||
|
|
||||||
req.AddData(&nl.XfrmUsersaFlush{Proto: uint8(proto)})
|
req.AddData(&nl.XfrmUsersaFlush{Proto: uint8(proto)})
|
||||||
|
|
||||||
_, err := req.Execute(unix.NETLINK_XFRM, 0)
|
_, err := req.Execute(syscall.NETLINK_XFRM, 0)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -430,16 +429,6 @@ func lftToLimits(lft *nl.XfrmLifetimeCfg, lmts *XfrmStateLimits) {
|
||||||
*lmts = *(*XfrmStateLimits)(unsafe.Pointer(lft))
|
*lmts = *(*XfrmStateLimits)(unsafe.Pointer(lft))
|
||||||
}
|
}
|
||||||
|
|
||||||
func curToStats(cur *nl.XfrmLifetimeCur, wstats *nl.XfrmStats, stats *XfrmStateStats) {
|
|
||||||
stats.Bytes = cur.Bytes
|
|
||||||
stats.Packets = cur.Packets
|
|
||||||
stats.AddTime = cur.AddTime
|
|
||||||
stats.UseTime = cur.UseTime
|
|
||||||
stats.ReplayWindow = wstats.ReplayWindow
|
|
||||||
stats.Replay = wstats.Replay
|
|
||||||
stats.Failed = wstats.IntegrityFailed
|
|
||||||
}
|
|
||||||
|
|
||||||
func xfrmUsersaInfoFromXfrmState(state *XfrmState) *nl.XfrmUsersaInfo {
|
func xfrmUsersaInfoFromXfrmState(state *XfrmState) *nl.XfrmUsersaInfo {
|
||||||
msg := &nl.XfrmUsersaInfo{}
|
msg := &nl.XfrmUsersaInfo{}
|
||||||
msg.Family = uint16(nl.GetIPFamily(state.Dst))
|
msg.Family = uint16(nl.GetIPFamily(state.Dst))
|
||||||
|
|
Loading…
Reference in New Issue