mirror of
https://github.com/moby/moby.git
synced 2022-11-09 12:21:53 -05:00
Vendor latest netlink library
- needed the methods to set the proper timeout Signed-off-by: Flavio Crisciani <flavio.crisciani@docker.com>
This commit is contained in:
parent
6736b223ec
commit
5b89af1bba
23 changed files with 898 additions and 160 deletions
|
@ -45,7 +45,7 @@ github.com/sirupsen/logrus v1.0.3
|
||||||
github.com/stretchr/testify dab07ac62d4905d3e48d17dc549c684ac3b7c15a
|
github.com/stretchr/testify dab07ac62d4905d3e48d17dc549c684ac3b7c15a
|
||||||
github.com/syndtr/gocapability db04d3cc01c8b54962a58ec7e491717d06cfcc16
|
github.com/syndtr/gocapability db04d3cc01c8b54962a58ec7e491717d06cfcc16
|
||||||
github.com/ugorji/go f1f1a805ed361a0e078bb537e4ea78cd37dcf065
|
github.com/ugorji/go f1f1a805ed361a0e078bb537e4ea78cd37dcf065
|
||||||
github.com/vishvananda/netlink bd6d5de5ccef2d66b0a26177928d0d8895d7f969
|
github.com/vishvananda/netlink b2de5d10e38ecce8607e6b438b6d174f389a004e
|
||||||
github.com/vishvananda/netns 604eaf189ee867d8c147fafc28def2394e878d25
|
github.com/vishvananda/netns 604eaf189ee867d8c147fafc28def2394e878d25
|
||||||
golang.org/x/crypto 558b6879de74bc843225cde5686419267ff707ca
|
golang.org/x/crypto 558b6879de74bc843225cde5686419267ff707ca
|
||||||
golang.org/x/net 7dcfb8076726a3fdd9353b6b8a1f1b6be6811bd6
|
golang.org/x/net 7dcfb8076726a3fdd9353b6b8a1f1b6be6811bd6
|
||||||
|
|
10
libnetwork/vendor/github.com/vishvananda/netlink/README.md
generated
vendored
10
libnetwork/vendor/github.com/vishvananda/netlink/README.md
generated
vendored
|
@ -38,15 +38,18 @@ Add a new bridge and add eth1 into it:
|
||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"net"
|
"fmt"
|
||||||
"github.com/vishvananda/netlink"
|
"github.com/vishvananda/netlink"
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
la := netlink.NewLinkAttrs()
|
la := netlink.NewLinkAttrs()
|
||||||
la.Name = "foo"
|
la.Name = "foo"
|
||||||
mybridge := &netlink.Bridge{la}}
|
mybridge := &netlink.Bridge{LinkAttrs: la}
|
||||||
_ := netlink.LinkAdd(mybridge)
|
err := netlink.LinkAdd(mybridge)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Printf("could not add %s: %v\n", la.Name, err)
|
||||||
|
}
|
||||||
eth1, _ := netlink.LinkByName("eth1")
|
eth1, _ := netlink.LinkByName("eth1")
|
||||||
netlink.LinkSetMaster(eth1, mybridge)
|
netlink.LinkSetMaster(eth1, mybridge)
|
||||||
}
|
}
|
||||||
|
@ -63,7 +66,6 @@ Add a new ip address to loopback:
|
||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"net"
|
|
||||||
"github.com/vishvananda/netlink"
|
"github.com/vishvananda/netlink"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
52
libnetwork/vendor/github.com/vishvananda/netlink/addr_linux.go
generated
vendored
52
libnetwork/vendor/github.com/vishvananda/netlink/addr_linux.go
generated
vendored
|
@ -2,7 +2,6 @@ package netlink
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"log"
|
|
||||||
"net"
|
"net"
|
||||||
"strings"
|
"strings"
|
||||||
"syscall"
|
"syscall"
|
||||||
|
@ -65,7 +64,7 @@ func (h *Handle) addrHandle(link Link, addr *Addr, req *nl.NetlinkRequest) error
|
||||||
msg := nl.NewIfAddrmsg(family)
|
msg := nl.NewIfAddrmsg(family)
|
||||||
msg.Index = uint32(base.Index)
|
msg.Index = uint32(base.Index)
|
||||||
msg.Scope = uint8(addr.Scope)
|
msg.Scope = uint8(addr.Scope)
|
||||||
prefixlen, _ := addr.Mask.Size()
|
prefixlen, masklen := addr.Mask.Size()
|
||||||
msg.Prefixlen = uint8(prefixlen)
|
msg.Prefixlen = uint8(prefixlen)
|
||||||
req.AddData(msg)
|
req.AddData(msg)
|
||||||
|
|
||||||
|
@ -103,9 +102,14 @@ func (h *Handle) addrHandle(link Link, addr *Addr, req *nl.NetlinkRequest) error
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if addr.Broadcast != nil {
|
if addr.Broadcast == nil {
|
||||||
req.AddData(nl.NewRtAttr(syscall.IFA_BROADCAST, addr.Broadcast))
|
calcBroadcast := make(net.IP, masklen/8)
|
||||||
|
for i := range localAddrData {
|
||||||
|
calcBroadcast[i] = localAddrData[i] | ^addr.Mask[i]
|
||||||
|
}
|
||||||
|
addr.Broadcast = calcBroadcast
|
||||||
}
|
}
|
||||||
|
req.AddData(nl.NewRtAttr(syscall.IFA_BROADCAST, addr.Broadcast))
|
||||||
|
|
||||||
if addr.Label != "" {
|
if addr.Label != "" {
|
||||||
labelData := nl.NewRtAttr(syscall.IFA_LABEL, nl.ZeroTerminated(addr.Label))
|
labelData := nl.NewRtAttr(syscall.IFA_LABEL, nl.ZeroTerminated(addr.Label))
|
||||||
|
@ -232,16 +236,34 @@ type AddrUpdate struct {
|
||||||
// AddrSubscribe takes a chan down which notifications will be sent
|
// AddrSubscribe takes a chan down which notifications will be sent
|
||||||
// when addresses change. Close the 'done' chan to stop subscription.
|
// when addresses change. Close the 'done' chan to stop subscription.
|
||||||
func AddrSubscribe(ch chan<- AddrUpdate, done <-chan struct{}) error {
|
func AddrSubscribe(ch chan<- AddrUpdate, done <-chan struct{}) error {
|
||||||
return addrSubscribe(netns.None(), netns.None(), ch, done)
|
return addrSubscribeAt(netns.None(), netns.None(), ch, done, nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
// AddrSubscribeAt works like AddrSubscribe plus it allows the caller
|
// AddrSubscribeAt works like AddrSubscribe plus it allows the caller
|
||||||
// to choose the network namespace in which to subscribe (ns).
|
// to choose the network namespace in which to subscribe (ns).
|
||||||
func AddrSubscribeAt(ns netns.NsHandle, ch chan<- AddrUpdate, done <-chan struct{}) error {
|
func AddrSubscribeAt(ns netns.NsHandle, ch chan<- AddrUpdate, done <-chan struct{}) error {
|
||||||
return addrSubscribe(ns, netns.None(), ch, done)
|
return addrSubscribeAt(ns, netns.None(), ch, done, nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
func addrSubscribe(newNs, curNs netns.NsHandle, ch chan<- AddrUpdate, done <-chan struct{}) error {
|
// AddrSubscribeOptions contains a set of options to use with
|
||||||
|
// AddrSubscribeWithOptions.
|
||||||
|
type AddrSubscribeOptions struct {
|
||||||
|
Namespace *netns.NsHandle
|
||||||
|
ErrorCallback func(error)
|
||||||
|
}
|
||||||
|
|
||||||
|
// AddrSubscribeWithOptions work like AddrSubscribe but enable to
|
||||||
|
// provide additional options to modify the behavior. Currently, the
|
||||||
|
// namespace can be provided as well as an error callback.
|
||||||
|
func AddrSubscribeWithOptions(ch chan<- AddrUpdate, done <-chan struct{}, options AddrSubscribeOptions) error {
|
||||||
|
if options.Namespace == nil {
|
||||||
|
none := netns.None()
|
||||||
|
options.Namespace = &none
|
||||||
|
}
|
||||||
|
return addrSubscribeAt(*options.Namespace, netns.None(), ch, done, options.ErrorCallback)
|
||||||
|
}
|
||||||
|
|
||||||
|
func addrSubscribeAt(newNs, curNs netns.NsHandle, ch chan<- AddrUpdate, done <-chan struct{}, cberr func(error)) error {
|
||||||
s, err := nl.SubscribeAt(newNs, curNs, syscall.NETLINK_ROUTE, syscall.RTNLGRP_IPV4_IFADDR, syscall.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
|
||||||
|
@ -257,20 +279,26 @@ func addrSubscribe(newNs, curNs netns.NsHandle, ch chan<- AddrUpdate, done <-cha
|
||||||
for {
|
for {
|
||||||
msgs, err := s.Receive()
|
msgs, err := s.Receive()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Printf("netlink.AddrSubscribe: Receive() error: %v", err)
|
if cberr != nil {
|
||||||
|
cberr(err)
|
||||||
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
for _, m := range msgs {
|
for _, m := range msgs {
|
||||||
msgType := m.Header.Type
|
msgType := m.Header.Type
|
||||||
if msgType != syscall.RTM_NEWADDR && msgType != syscall.RTM_DELADDR {
|
if msgType != syscall.RTM_NEWADDR && msgType != syscall.RTM_DELADDR {
|
||||||
log.Printf("netlink.AddrSubscribe: bad message type: %d", msgType)
|
if cberr != nil {
|
||||||
continue
|
cberr(fmt.Errorf("bad message type: %d", msgType))
|
||||||
|
}
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
addr, _, ifindex, err := parseAddr(m.Data)
|
addr, _, ifindex, err := parseAddr(m.Data)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Printf("netlink.AddrSubscribe: could not parse address: %v", err)
|
if cberr != nil {
|
||||||
continue
|
cberr(fmt.Errorf("could not parse address: %v", err))
|
||||||
|
}
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
ch <- AddrUpdate{LinkAddress: *addr.IPNet,
|
ch <- AddrUpdate{LinkAddress: *addr.IPNet,
|
||||||
|
|
115
libnetwork/vendor/github.com/vishvananda/netlink/bridge_linux.go
generated
vendored
Normal file
115
libnetwork/vendor/github.com/vishvananda/netlink/bridge_linux.go
generated
vendored
Normal file
|
@ -0,0 +1,115 @@
|
||||||
|
package netlink
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"syscall"
|
||||||
|
|
||||||
|
"github.com/vishvananda/netlink/nl"
|
||||||
|
)
|
||||||
|
|
||||||
|
// BridgeVlanList gets a map of device id to bridge vlan infos.
|
||||||
|
// Equivalent to: `bridge vlan show`
|
||||||
|
func BridgeVlanList() (map[int32][]*nl.BridgeVlanInfo, error) {
|
||||||
|
return pkgHandle.BridgeVlanList()
|
||||||
|
}
|
||||||
|
|
||||||
|
// BridgeVlanList gets a map of device id to bridge vlan infos.
|
||||||
|
// Equivalent to: `bridge vlan show`
|
||||||
|
func (h *Handle) BridgeVlanList() (map[int32][]*nl.BridgeVlanInfo, error) {
|
||||||
|
req := h.newNetlinkRequest(syscall.RTM_GETLINK, syscall.NLM_F_DUMP)
|
||||||
|
msg := nl.NewIfInfomsg(syscall.AF_BRIDGE)
|
||||||
|
req.AddData(msg)
|
||||||
|
req.AddData(nl.NewRtAttr(nl.IFLA_EXT_MASK, nl.Uint32Attr(uint32(nl.RTEXT_FILTER_BRVLAN))))
|
||||||
|
|
||||||
|
msgs, err := req.Execute(syscall.NETLINK_ROUTE, syscall.RTM_NEWLINK)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
ret := make(map[int32][]*nl.BridgeVlanInfo)
|
||||||
|
for _, m := range msgs {
|
||||||
|
msg := nl.DeserializeIfInfomsg(m)
|
||||||
|
|
||||||
|
attrs, err := nl.ParseRouteAttr(m[msg.Len():])
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
for _, attr := range attrs {
|
||||||
|
switch attr.Attr.Type {
|
||||||
|
case nl.IFLA_AF_SPEC:
|
||||||
|
//nested attr
|
||||||
|
nestAttrs, err := nl.ParseRouteAttr(attr.Value)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("failed to parse nested attr %v", err)
|
||||||
|
}
|
||||||
|
for _, nestAttr := range nestAttrs {
|
||||||
|
switch nestAttr.Attr.Type {
|
||||||
|
case nl.IFLA_BRIDGE_VLAN_INFO:
|
||||||
|
vlanInfo := nl.DeserializeBridgeVlanInfo(nestAttr.Value)
|
||||||
|
ret[msg.Index] = append(ret[msg.Index], vlanInfo)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ret, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// BridgeVlanAdd adds a new vlan filter entry
|
||||||
|
// Equivalent to: `bridge vlan add dev DEV vid VID [ pvid ] [ untagged ] [ self ] [ master ]`
|
||||||
|
func BridgeVlanAdd(link Link, vid uint16, pvid, untagged, self, master bool) error {
|
||||||
|
return pkgHandle.BridgeVlanAdd(link, vid, pvid, untagged, self, master)
|
||||||
|
}
|
||||||
|
|
||||||
|
// BridgeVlanAdd adds a new vlan filter entry
|
||||||
|
// 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 {
|
||||||
|
return h.bridgeVlanModify(syscall.RTM_SETLINK, link, vid, pvid, untagged, self, master)
|
||||||
|
}
|
||||||
|
|
||||||
|
// BridgeVlanDel adds a new vlan filter entry
|
||||||
|
// Equivalent to: `bridge vlan del dev DEV vid VID [ pvid ] [ untagged ] [ self ] [ master ]`
|
||||||
|
func BridgeVlanDel(link Link, vid uint16, pvid, untagged, self, master bool) error {
|
||||||
|
return pkgHandle.BridgeVlanDel(link, vid, pvid, untagged, self, master)
|
||||||
|
}
|
||||||
|
|
||||||
|
// BridgeVlanDel adds a new vlan filter entry
|
||||||
|
// 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 {
|
||||||
|
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 {
|
||||||
|
base := link.Attrs()
|
||||||
|
h.ensureIndex(base)
|
||||||
|
req := h.newNetlinkRequest(cmd, syscall.NLM_F_ACK)
|
||||||
|
|
||||||
|
msg := nl.NewIfInfomsg(syscall.AF_BRIDGE)
|
||||||
|
msg.Index = int32(base.Index)
|
||||||
|
req.AddData(msg)
|
||||||
|
|
||||||
|
br := nl.NewRtAttr(nl.IFLA_AF_SPEC, nil)
|
||||||
|
var flags uint16
|
||||||
|
if self {
|
||||||
|
flags |= nl.BRIDGE_FLAGS_SELF
|
||||||
|
}
|
||||||
|
if master {
|
||||||
|
flags |= nl.BRIDGE_FLAGS_MASTER
|
||||||
|
}
|
||||||
|
if flags > 0 {
|
||||||
|
nl.NewRtAttrChild(br, nl.IFLA_BRIDGE_FLAGS, nl.Uint16Attr(flags))
|
||||||
|
}
|
||||||
|
vlanInfo := &nl.BridgeVlanInfo{Vid: vid}
|
||||||
|
if pvid {
|
||||||
|
vlanInfo.Flags |= nl.BRIDGE_VLAN_INFO_PVID
|
||||||
|
}
|
||||||
|
if untagged {
|
||||||
|
vlanInfo.Flags |= nl.BRIDGE_VLAN_INFO_UNTAGGED
|
||||||
|
}
|
||||||
|
nl.NewRtAttrChild(br, nl.IFLA_BRIDGE_VLAN_INFO, vlanInfo.Serialize())
|
||||||
|
req.AddData(br)
|
||||||
|
_, err := req.Execute(syscall.NETLINK_ROUTE, 0)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
45
libnetwork/vendor/github.com/vishvananda/netlink/conntrack_linux.go
generated
vendored
45
libnetwork/vendor/github.com/vishvananda/netlink/conntrack_linux.go
generated
vendored
|
@ -22,7 +22,11 @@ const (
|
||||||
// https://github.com/torvalds/linux/blob/master/include/uapi/linux/netfilter/nfnetlink.h -> #define NFNL_SUBSYS_CTNETLINK_EXP 2
|
// https://github.com/torvalds/linux/blob/master/include/uapi/linux/netfilter/nfnetlink.h -> #define NFNL_SUBSYS_CTNETLINK_EXP 2
|
||||||
ConntrackExpectTable = 2
|
ConntrackExpectTable = 2
|
||||||
)
|
)
|
||||||
|
const (
|
||||||
|
// For Parsing Mark
|
||||||
|
TCP_PROTO = 6
|
||||||
|
UDP_PROTO = 17
|
||||||
|
)
|
||||||
const (
|
const (
|
||||||
// backward compatibility with golang 1.6 which does not have io.SeekCurrent
|
// backward compatibility with golang 1.6 which does not have io.SeekCurrent
|
||||||
seekCurrent = 1
|
seekCurrent = 1
|
||||||
|
@ -56,7 +60,7 @@ func ConntrackTableFlush(table ConntrackTableType) error {
|
||||||
|
|
||||||
// ConntrackDeleteFilter deletes entries on the specified table on the base of the filter
|
// ConntrackDeleteFilter deletes entries on the specified table on the base of the filter
|
||||||
// conntrack -D [table] parameters Delete conntrack or expectation
|
// conntrack -D [table] parameters Delete conntrack or expectation
|
||||||
func ConntrackDeleteFilter(table ConntrackTableType, family InetFamily, filter *ConntrackFilter) (uint, error) {
|
func ConntrackDeleteFilter(table ConntrackTableType, family InetFamily, filter CustomConntrackFilter) (uint, error) {
|
||||||
return pkgHandle.ConntrackDeleteFilter(table, family, filter)
|
return pkgHandle.ConntrackDeleteFilter(table, family, filter)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -88,7 +92,7 @@ func (h *Handle) ConntrackTableFlush(table ConntrackTableType) error {
|
||||||
|
|
||||||
// ConntrackDeleteFilter deletes entries on the specified table on the base of the filter using the netlink handle passed
|
// ConntrackDeleteFilter deletes entries on the specified table on the base of the filter using the netlink handle passed
|
||||||
// conntrack -D [table] parameters Delete conntrack or expectation
|
// conntrack -D [table] parameters Delete conntrack or expectation
|
||||||
func (h *Handle) ConntrackDeleteFilter(table ConntrackTableType, family InetFamily, filter *ConntrackFilter) (uint, error) {
|
func (h *Handle) ConntrackDeleteFilter(table ConntrackTableType, family InetFamily, filter CustomConntrackFilter) (uint, error) {
|
||||||
res, err := h.dumpConntrackTable(table, family)
|
res, err := h.dumpConntrackTable(table, family)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, err
|
return 0, err
|
||||||
|
@ -142,15 +146,16 @@ type ConntrackFlow struct {
|
||||||
FamilyType uint8
|
FamilyType uint8
|
||||||
Forward ipTuple
|
Forward ipTuple
|
||||||
Reverse ipTuple
|
Reverse ipTuple
|
||||||
|
Mark uint32
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *ConntrackFlow) String() string {
|
func (s *ConntrackFlow) String() string {
|
||||||
// conntrack cmd output:
|
// conntrack cmd output:
|
||||||
// udp 17 src=127.0.0.1 dst=127.0.0.1 sport=4001 dport=1234 [UNREPLIED] src=127.0.0.1 dst=127.0.0.1 sport=1234 dport=4001
|
// udp 17 src=127.0.0.1 dst=127.0.0.1 sport=4001 dport=1234 [UNREPLIED] src=127.0.0.1 dst=127.0.0.1 sport=1234 dport=4001 mark=0
|
||||||
return fmt.Sprintf("%s\t%d src=%s dst=%s sport=%d dport=%d\tsrc=%s dst=%s sport=%d dport=%d",
|
return fmt.Sprintf("%s\t%d src=%s dst=%s sport=%d dport=%d\tsrc=%s dst=%s sport=%d dport=%d mark=%d",
|
||||||
nl.L4ProtoMap[s.Forward.Protocol], s.Forward.Protocol,
|
nl.L4ProtoMap[s.Forward.Protocol], s.Forward.Protocol,
|
||||||
s.Forward.SrcIP.String(), s.Forward.DstIP.String(), s.Forward.SrcPort, s.Forward.DstPort,
|
s.Forward.SrcIP.String(), s.Forward.DstIP.String(), s.Forward.SrcPort, s.Forward.DstPort,
|
||||||
s.Reverse.SrcIP.String(), s.Reverse.DstIP.String(), s.Reverse.SrcPort, s.Reverse.DstPort)
|
s.Reverse.SrcIP.String(), s.Reverse.DstIP.String(), s.Reverse.SrcPort, s.Reverse.DstPort, s.Mark)
|
||||||
}
|
}
|
||||||
|
|
||||||
// This method parse the ip tuple structure
|
// This method parse the ip tuple structure
|
||||||
|
@ -160,7 +165,7 @@ func (s *ConntrackFlow) String() string {
|
||||||
// <len, NLA_F_NESTED|nl.CTA_TUPLE_PROTO, 1 byte for the protocol, 3 bytes of padding>
|
// <len, NLA_F_NESTED|nl.CTA_TUPLE_PROTO, 1 byte for the protocol, 3 bytes of padding>
|
||||||
// <len, CTA_PROTO_SRC_PORT, 2 bytes for the source port, 2 bytes of padding>
|
// <len, CTA_PROTO_SRC_PORT, 2 bytes for the source port, 2 bytes of padding>
|
||||||
// <len, CTA_PROTO_DST_PORT, 2 bytes for the source port, 2 bytes of padding>
|
// <len, CTA_PROTO_DST_PORT, 2 bytes for the source port, 2 bytes of padding>
|
||||||
func parseIpTuple(reader *bytes.Reader, tpl *ipTuple) {
|
func parseIpTuple(reader *bytes.Reader, tpl *ipTuple) uint8 {
|
||||||
for i := 0; i < 2; i++ {
|
for i := 0; i < 2; i++ {
|
||||||
_, t, _, v := parseNfAttrTLV(reader)
|
_, t, _, v := parseNfAttrTLV(reader)
|
||||||
switch t {
|
switch t {
|
||||||
|
@ -189,6 +194,7 @@ func parseIpTuple(reader *bytes.Reader, tpl *ipTuple) {
|
||||||
// Skip some padding 2 byte
|
// Skip some padding 2 byte
|
||||||
reader.Seek(2, seekCurrent)
|
reader.Seek(2, seekCurrent)
|
||||||
}
|
}
|
||||||
|
return tpl.Protocol
|
||||||
}
|
}
|
||||||
|
|
||||||
func parseNfAttrTLV(r *bytes.Reader) (isNested bool, attrType, len uint16, value []byte) {
|
func parseNfAttrTLV(r *bytes.Reader) (isNested bool, attrType, len uint16, value []byte) {
|
||||||
|
@ -216,6 +222,7 @@ func parseBERaw16(r *bytes.Reader, v *uint16) {
|
||||||
|
|
||||||
func parseRawData(data []byte) *ConntrackFlow {
|
func parseRawData(data []byte) *ConntrackFlow {
|
||||||
s := &ConntrackFlow{}
|
s := &ConntrackFlow{}
|
||||||
|
var proto uint8
|
||||||
// First there is the Nfgenmsg header
|
// First there is the Nfgenmsg header
|
||||||
// consume only the family field
|
// consume only the family field
|
||||||
reader := bytes.NewReader(data)
|
reader := bytes.NewReader(data)
|
||||||
|
@ -234,7 +241,7 @@ func parseRawData(data []byte) *ConntrackFlow {
|
||||||
nested, t, l := parseNfAttrTL(reader)
|
nested, t, l := parseNfAttrTL(reader)
|
||||||
if nested && t == nl.CTA_TUPLE_ORIG {
|
if nested && t == nl.CTA_TUPLE_ORIG {
|
||||||
if nested, t, _ = parseNfAttrTL(reader); nested && t == nl.CTA_TUPLE_IP {
|
if nested, t, _ = parseNfAttrTL(reader); nested && t == nl.CTA_TUPLE_IP {
|
||||||
parseIpTuple(reader, &s.Forward)
|
proto = parseIpTuple(reader, &s.Forward)
|
||||||
}
|
}
|
||||||
} else if nested && t == nl.CTA_TUPLE_REPLY {
|
} else if nested && t == nl.CTA_TUPLE_REPLY {
|
||||||
if nested, t, _ = parseNfAttrTL(reader); nested && t == nl.CTA_TUPLE_IP {
|
if nested, t, _ = parseNfAttrTL(reader); nested && t == nl.CTA_TUPLE_IP {
|
||||||
|
@ -248,7 +255,19 @@ func parseRawData(data []byte) *ConntrackFlow {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if proto == TCP_PROTO {
|
||||||
|
reader.Seek(64, seekCurrent)
|
||||||
|
_, t, _, v := parseNfAttrTLV(reader)
|
||||||
|
if t == nl.CTA_MARK {
|
||||||
|
s.Mark = uint32(v[3])
|
||||||
|
}
|
||||||
|
} else if proto == UDP_PROTO {
|
||||||
|
reader.Seek(16, seekCurrent)
|
||||||
|
_, t, _, v := parseNfAttrTLV(reader)
|
||||||
|
if t == nl.CTA_MARK {
|
||||||
|
s.Mark = uint32(v[3])
|
||||||
|
}
|
||||||
|
}
|
||||||
return s
|
return s
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -290,6 +309,12 @@ const (
|
||||||
ConntrackNatAnyIP // -any-nat ip Source or destination NAT ip
|
ConntrackNatAnyIP // -any-nat ip Source or destination NAT ip
|
||||||
)
|
)
|
||||||
|
|
||||||
|
type CustomConntrackFilter interface {
|
||||||
|
// MatchConntrackFlow applies the filter to the flow and returns true if the flow matches
|
||||||
|
// the filter or false otherwise
|
||||||
|
MatchConntrackFlow(flow *ConntrackFlow) bool
|
||||||
|
}
|
||||||
|
|
||||||
type ConntrackFilter struct {
|
type ConntrackFilter struct {
|
||||||
ipFilter map[ConntrackFilterType]net.IP
|
ipFilter map[ConntrackFilterType]net.IP
|
||||||
}
|
}
|
||||||
|
@ -342,3 +367,5 @@ func (f *ConntrackFilter) MatchConntrackFlow(flow *ConntrackFlow) bool {
|
||||||
|
|
||||||
return match
|
return match
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var _ CustomConntrackFilter = (*ConntrackFilter)(nil)
|
||||||
|
|
10
libnetwork/vendor/github.com/vishvananda/netlink/filter.go
generated
vendored
10
libnetwork/vendor/github.com/vishvananda/netlink/filter.go
generated
vendored
|
@ -2,8 +2,6 @@ package netlink
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
"github.com/vishvananda/netlink/nl"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type Filter interface {
|
type Filter interface {
|
||||||
|
@ -184,14 +182,6 @@ func NewMirredAction(redirIndex int) *MirredAction {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Constants used in TcU32Sel.Flags.
|
|
||||||
const (
|
|
||||||
TC_U32_TERMINAL = nl.TC_U32_TERMINAL
|
|
||||||
TC_U32_OFFSET = nl.TC_U32_OFFSET
|
|
||||||
TC_U32_VAROFFSET = nl.TC_U32_VAROFFSET
|
|
||||||
TC_U32_EAT = nl.TC_U32_EAT
|
|
||||||
)
|
|
||||||
|
|
||||||
// Sel of the U32 filters that contains multiple TcU32Key. This is the copy
|
// Sel of the U32 filters that contains multiple TcU32Key. This is the copy
|
||||||
// and the frontend representation of nl.TcU32Sel. It is serialized into canonical
|
// and the frontend representation of nl.TcU32Sel. It is serialized into canonical
|
||||||
// nl.TcU32Sel with the appropriate endianness.
|
// nl.TcU32Sel with the appropriate endianness.
|
||||||
|
|
66
libnetwork/vendor/github.com/vishvananda/netlink/filter_linux.go
generated
vendored
66
libnetwork/vendor/github.com/vishvananda/netlink/filter_linux.go
generated
vendored
|
@ -11,6 +11,14 @@ import (
|
||||||
"github.com/vishvananda/netlink/nl"
|
"github.com/vishvananda/netlink/nl"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// Constants used in TcU32Sel.Flags.
|
||||||
|
const (
|
||||||
|
TC_U32_TERMINAL = nl.TC_U32_TERMINAL
|
||||||
|
TC_U32_OFFSET = nl.TC_U32_OFFSET
|
||||||
|
TC_U32_VAROFFSET = nl.TC_U32_VAROFFSET
|
||||||
|
TC_U32_EAT = nl.TC_U32_EAT
|
||||||
|
)
|
||||||
|
|
||||||
// Fw filter filters on firewall marks
|
// Fw filter filters on firewall marks
|
||||||
// NOTE: this is in filter_linux because it refers to nl.TcPolice which
|
// NOTE: this is in filter_linux because it refers to nl.TcPolice which
|
||||||
// is defined in nl/tc_linux.go
|
// is defined in nl/tc_linux.go
|
||||||
|
@ -128,9 +136,11 @@ func (h *Handle) FilterAdd(filter Filter) error {
|
||||||
req.AddData(nl.NewRtAttr(nl.TCA_KIND, nl.ZeroTerminated(filter.Type())))
|
req.AddData(nl.NewRtAttr(nl.TCA_KIND, nl.ZeroTerminated(filter.Type())))
|
||||||
|
|
||||||
options := nl.NewRtAttr(nl.TCA_OPTIONS, nil)
|
options := nl.NewRtAttr(nl.TCA_OPTIONS, nil)
|
||||||
if u32, ok := filter.(*U32); ok {
|
|
||||||
|
switch filter := filter.(type) {
|
||||||
|
case *U32:
|
||||||
// Convert TcU32Sel into nl.TcU32Sel as it is without copy.
|
// Convert TcU32Sel into nl.TcU32Sel as it is without copy.
|
||||||
sel := (*nl.TcU32Sel)(unsafe.Pointer(u32.Sel))
|
sel := (*nl.TcU32Sel)(unsafe.Pointer(filter.Sel))
|
||||||
if sel == nil {
|
if sel == nil {
|
||||||
// match all
|
// match all
|
||||||
sel = &nl.TcU32Sel{
|
sel = &nl.TcU32Sel{
|
||||||
|
@ -158,56 +168,56 @@ func (h *Handle) FilterAdd(filter Filter) error {
|
||||||
}
|
}
|
||||||
sel.Nkeys = uint8(len(sel.Keys))
|
sel.Nkeys = uint8(len(sel.Keys))
|
||||||
nl.NewRtAttrChild(options, nl.TCA_U32_SEL, sel.Serialize())
|
nl.NewRtAttrChild(options, nl.TCA_U32_SEL, sel.Serialize())
|
||||||
if u32.ClassId != 0 {
|
if filter.ClassId != 0 {
|
||||||
nl.NewRtAttrChild(options, nl.TCA_U32_CLASSID, nl.Uint32Attr(u32.ClassId))
|
nl.NewRtAttrChild(options, nl.TCA_U32_CLASSID, nl.Uint32Attr(filter.ClassId))
|
||||||
}
|
}
|
||||||
actionsAttr := nl.NewRtAttrChild(options, nl.TCA_U32_ACT, nil)
|
actionsAttr := nl.NewRtAttrChild(options, nl.TCA_U32_ACT, nil)
|
||||||
// backwards compatibility
|
// backwards compatibility
|
||||||
if u32.RedirIndex != 0 {
|
if filter.RedirIndex != 0 {
|
||||||
u32.Actions = append([]Action{NewMirredAction(u32.RedirIndex)}, u32.Actions...)
|
filter.Actions = append([]Action{NewMirredAction(filter.RedirIndex)}, filter.Actions...)
|
||||||
}
|
}
|
||||||
if err := EncodeActions(actionsAttr, u32.Actions); err != nil {
|
if err := EncodeActions(actionsAttr, filter.Actions); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
} else if fw, ok := filter.(*Fw); ok {
|
case *Fw:
|
||||||
if fw.Mask != 0 {
|
if filter.Mask != 0 {
|
||||||
b := make([]byte, 4)
|
b := make([]byte, 4)
|
||||||
native.PutUint32(b, fw.Mask)
|
native.PutUint32(b, filter.Mask)
|
||||||
nl.NewRtAttrChild(options, nl.TCA_FW_MASK, b)
|
nl.NewRtAttrChild(options, nl.TCA_FW_MASK, b)
|
||||||
}
|
}
|
||||||
if fw.InDev != "" {
|
if filter.InDev != "" {
|
||||||
nl.NewRtAttrChild(options, nl.TCA_FW_INDEV, nl.ZeroTerminated(fw.InDev))
|
nl.NewRtAttrChild(options, nl.TCA_FW_INDEV, nl.ZeroTerminated(filter.InDev))
|
||||||
}
|
}
|
||||||
if (fw.Police != nl.TcPolice{}) {
|
if (filter.Police != nl.TcPolice{}) {
|
||||||
|
|
||||||
police := nl.NewRtAttrChild(options, nl.TCA_FW_POLICE, nil)
|
police := nl.NewRtAttrChild(options, nl.TCA_FW_POLICE, nil)
|
||||||
nl.NewRtAttrChild(police, nl.TCA_POLICE_TBF, fw.Police.Serialize())
|
nl.NewRtAttrChild(police, nl.TCA_POLICE_TBF, filter.Police.Serialize())
|
||||||
if (fw.Police.Rate != nl.TcRateSpec{}) {
|
if (filter.Police.Rate != nl.TcRateSpec{}) {
|
||||||
payload := SerializeRtab(fw.Rtab)
|
payload := SerializeRtab(filter.Rtab)
|
||||||
nl.NewRtAttrChild(police, nl.TCA_POLICE_RATE, payload)
|
nl.NewRtAttrChild(police, nl.TCA_POLICE_RATE, payload)
|
||||||
}
|
}
|
||||||
if (fw.Police.PeakRate != nl.TcRateSpec{}) {
|
if (filter.Police.PeakRate != nl.TcRateSpec{}) {
|
||||||
payload := SerializeRtab(fw.Ptab)
|
payload := SerializeRtab(filter.Ptab)
|
||||||
nl.NewRtAttrChild(police, nl.TCA_POLICE_PEAKRATE, payload)
|
nl.NewRtAttrChild(police, nl.TCA_POLICE_PEAKRATE, payload)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if fw.ClassId != 0 {
|
if filter.ClassId != 0 {
|
||||||
b := make([]byte, 4)
|
b := make([]byte, 4)
|
||||||
native.PutUint32(b, fw.ClassId)
|
native.PutUint32(b, filter.ClassId)
|
||||||
nl.NewRtAttrChild(options, nl.TCA_FW_CLASSID, b)
|
nl.NewRtAttrChild(options, nl.TCA_FW_CLASSID, b)
|
||||||
}
|
}
|
||||||
} else if bpf, ok := filter.(*BpfFilter); ok {
|
case *BpfFilter:
|
||||||
var bpfFlags uint32
|
var bpfFlags uint32
|
||||||
if bpf.ClassId != 0 {
|
if filter.ClassId != 0 {
|
||||||
nl.NewRtAttrChild(options, nl.TCA_BPF_CLASSID, nl.Uint32Attr(bpf.ClassId))
|
nl.NewRtAttrChild(options, nl.TCA_BPF_CLASSID, nl.Uint32Attr(filter.ClassId))
|
||||||
}
|
}
|
||||||
if bpf.Fd >= 0 {
|
if filter.Fd >= 0 {
|
||||||
nl.NewRtAttrChild(options, nl.TCA_BPF_FD, nl.Uint32Attr((uint32(bpf.Fd))))
|
nl.NewRtAttrChild(options, nl.TCA_BPF_FD, nl.Uint32Attr((uint32(filter.Fd))))
|
||||||
}
|
}
|
||||||
if bpf.Name != "" {
|
if filter.Name != "" {
|
||||||
nl.NewRtAttrChild(options, nl.TCA_BPF_NAME, nl.ZeroTerminated(bpf.Name))
|
nl.NewRtAttrChild(options, nl.TCA_BPF_NAME, nl.ZeroTerminated(filter.Name))
|
||||||
}
|
}
|
||||||
if bpf.DirectAction {
|
if filter.DirectAction {
|
||||||
bpfFlags |= nl.TCA_BPF_FLAG_ACT_DIRECT
|
bpfFlags |= nl.TCA_BPF_FLAG_ACT_DIRECT
|
||||||
}
|
}
|
||||||
nl.NewRtAttrChild(options, nl.TCA_BPF_FLAGS, nl.Uint32Attr(bpfFlags))
|
nl.NewRtAttrChild(options, nl.TCA_BPF_FLAGS, nl.Uint32Attr(bpfFlags))
|
||||||
|
|
41
libnetwork/vendor/github.com/vishvananda/netlink/handle_linux.go
generated
vendored
41
libnetwork/vendor/github.com/vishvananda/netlink/handle_linux.go
generated
vendored
|
@ -45,12 +45,27 @@ func (h *Handle) SetSocketTimeout(to time.Duration) error {
|
||||||
}
|
}
|
||||||
tv := syscall.NsecToTimeval(to.Nanoseconds())
|
tv := syscall.NsecToTimeval(to.Nanoseconds())
|
||||||
for _, sh := range h.sockets {
|
for _, sh := range h.sockets {
|
||||||
fd := sh.Socket.GetFd()
|
if err := sh.Socket.SetSendTimeout(&tv); err != nil {
|
||||||
err := syscall.SetsockoptTimeval(fd, syscall.SOL_SOCKET, syscall.SO_RCVTIMEO, &tv)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
err = syscall.SetsockoptTimeval(fd, syscall.SOL_SOCKET, syscall.SO_SNDTIMEO, &tv)
|
if err := sh.Socket.SetReceiveTimeout(&tv); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetSocketReceiveBufferSize sets the receive buffer size for each
|
||||||
|
// socket in the netlink handle. The maximum value is capped by
|
||||||
|
// /proc/sys/net/core/rmem_max.
|
||||||
|
func (h *Handle) SetSocketReceiveBufferSize(size int, force bool) error {
|
||||||
|
opt := syscall.SO_RCVBUF
|
||||||
|
if force {
|
||||||
|
opt = syscall.SO_RCVBUFFORCE
|
||||||
|
}
|
||||||
|
for _, sh := range h.sockets {
|
||||||
|
fd := sh.Socket.GetFd()
|
||||||
|
err := syscall.SetsockoptInt(fd, syscall.SOL_SOCKET, opt, size)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -58,6 +73,24 @@ func (h *Handle) SetSocketTimeout(to time.Duration) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GetSocketReceiveBufferSize gets the receiver buffer size for each
|
||||||
|
// socket in the netlink handle. The retrieved value should be the
|
||||||
|
// double to the one set for SetSocketReceiveBufferSize.
|
||||||
|
func (h *Handle) GetSocketReceiveBufferSize() ([]int, error) {
|
||||||
|
results := make([]int, len(h.sockets))
|
||||||
|
i := 0
|
||||||
|
for _, sh := range h.sockets {
|
||||||
|
fd := sh.Socket.GetFd()
|
||||||
|
size, err := syscall.GetsockoptInt(fd, syscall.SOL_SOCKET, syscall.SO_RCVBUF)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
results[i] = size
|
||||||
|
i++
|
||||||
|
}
|
||||||
|
return results, nil
|
||||||
|
}
|
||||||
|
|
||||||
// NewHandle returns a netlink handle on the network namespace
|
// NewHandle returns a netlink handle on the network namespace
|
||||||
// specified by ns. If ns=netns.None(), current network namespace
|
// specified by ns. If ns=netns.None(), current network namespace
|
||||||
// will be assumed
|
// will be assumed
|
||||||
|
|
4
libnetwork/vendor/github.com/vishvananda/netlink/handle_unspecified.go
generated
vendored
4
libnetwork/vendor/github.com/vishvananda/netlink/handle_unspecified.go
generated
vendored
|
@ -145,6 +145,10 @@ func (h *Handle) LinkSetFlood(link Link, mode bool) error {
|
||||||
return ErrNotImplemented
|
return ErrNotImplemented
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (h *Handle) LinkSetTxQLen(link Link, qlen int) error {
|
||||||
|
return ErrNotImplemented
|
||||||
|
}
|
||||||
|
|
||||||
func (h *Handle) setProtinfoAttr(link Link, mode bool, attr int) error {
|
func (h *Handle) setProtinfoAttr(link Link, mode bool, attr int) error {
|
||||||
return ErrNotImplemented
|
return ErrNotImplemented
|
||||||
}
|
}
|
||||||
|
|
26
libnetwork/vendor/github.com/vishvananda/netlink/link.go
generated
vendored
26
libnetwork/vendor/github.com/vishvananda/netlink/link.go
generated
vendored
|
@ -37,6 +37,7 @@ type LinkAttrs struct {
|
||||||
EncapType string
|
EncapType string
|
||||||
Protinfo *Protinfo
|
Protinfo *Protinfo
|
||||||
OperState LinkOperState
|
OperState LinkOperState
|
||||||
|
NetNsID int
|
||||||
}
|
}
|
||||||
|
|
||||||
// LinkOperState represents the values of the IFLA_OPERSTATE link
|
// LinkOperState represents the values of the IFLA_OPERSTATE link
|
||||||
|
@ -171,6 +172,7 @@ type LinkXdp struct {
|
||||||
Fd int
|
Fd int
|
||||||
Attached bool
|
Attached bool
|
||||||
Flags uint32
|
Flags uint32
|
||||||
|
ProgId uint32
|
||||||
}
|
}
|
||||||
|
|
||||||
// Device links cannot be created via netlink. These links
|
// Device links cannot be created via netlink. These links
|
||||||
|
@ -339,6 +341,7 @@ type Vxlan struct {
|
||||||
UDPCSum bool
|
UDPCSum bool
|
||||||
NoAge bool
|
NoAge bool
|
||||||
GBP bool
|
GBP bool
|
||||||
|
FlowBased bool
|
||||||
Age int
|
Age int
|
||||||
Limit int
|
Limit int
|
||||||
Port int
|
Port int
|
||||||
|
@ -684,6 +687,7 @@ type Gretap struct {
|
||||||
EncapType uint16
|
EncapType uint16
|
||||||
EncapFlags uint16
|
EncapFlags uint16
|
||||||
Link uint32
|
Link uint32
|
||||||
|
FlowBased bool
|
||||||
}
|
}
|
||||||
|
|
||||||
func (gretap *Gretap) Attrs() *LinkAttrs {
|
func (gretap *Gretap) Attrs() *LinkAttrs {
|
||||||
|
@ -729,6 +733,28 @@ func (iptun *Vti) Type() string {
|
||||||
return "vti"
|
return "vti"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type Gretun struct {
|
||||||
|
LinkAttrs
|
||||||
|
Link uint32
|
||||||
|
IFlags uint16
|
||||||
|
OFlags uint16
|
||||||
|
IKey uint32
|
||||||
|
OKey uint32
|
||||||
|
Local net.IP
|
||||||
|
Remote net.IP
|
||||||
|
Ttl uint8
|
||||||
|
Tos uint8
|
||||||
|
PMtuDisc uint8
|
||||||
|
}
|
||||||
|
|
||||||
|
func (gretun *Gretun) Attrs() *LinkAttrs {
|
||||||
|
return &gretun.LinkAttrs
|
||||||
|
}
|
||||||
|
|
||||||
|
func (gretun *Gretun) Type() string {
|
||||||
|
return "gre"
|
||||||
|
}
|
||||||
|
|
||||||
type Vrf struct {
|
type Vrf struct {
|
||||||
LinkAttrs
|
LinkAttrs
|
||||||
Table uint32
|
Table uint32
|
||||||
|
|
286
libnetwork/vendor/github.com/vishvananda/netlink/link_linux.go
generated
vendored
286
libnetwork/vendor/github.com/vishvananda/netlink/link_linux.go
generated
vendored
|
@ -379,6 +379,74 @@ func (h *Handle) LinkSetVfTxRate(link Link, vf, rate int) error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// LinkSetVfSpoofchk enables/disables spoof check on a vf for the link.
|
||||||
|
// Equivalent to: `ip link set $link vf $vf spoofchk $check`
|
||||||
|
func LinkSetVfSpoofchk(link Link, vf int, check bool) error {
|
||||||
|
return pkgHandle.LinkSetVfSpoofchk(link, vf, check)
|
||||||
|
}
|
||||||
|
|
||||||
|
// LinkSetVfSpookfchk enables/disables spoof check on a vf for the link.
|
||||||
|
// Equivalent to: `ip link set $link vf $vf spoofchk $check`
|
||||||
|
func (h *Handle) LinkSetVfSpoofchk(link Link, vf int, check bool) error {
|
||||||
|
var setting uint32
|
||||||
|
base := link.Attrs()
|
||||||
|
h.ensureIndex(base)
|
||||||
|
req := h.newNetlinkRequest(syscall.RTM_SETLINK, syscall.NLM_F_ACK)
|
||||||
|
|
||||||
|
msg := nl.NewIfInfomsg(syscall.AF_UNSPEC)
|
||||||
|
msg.Index = int32(base.Index)
|
||||||
|
req.AddData(msg)
|
||||||
|
|
||||||
|
data := nl.NewRtAttr(nl.IFLA_VFINFO_LIST, nil)
|
||||||
|
info := nl.NewRtAttrChild(data, nl.IFLA_VF_INFO, nil)
|
||||||
|
if check {
|
||||||
|
setting = 1
|
||||||
|
}
|
||||||
|
vfmsg := nl.VfSpoofchk{
|
||||||
|
Vf: uint32(vf),
|
||||||
|
Setting: setting,
|
||||||
|
}
|
||||||
|
nl.NewRtAttrChild(info, nl.IFLA_VF_SPOOFCHK, vfmsg.Serialize())
|
||||||
|
req.AddData(data)
|
||||||
|
|
||||||
|
_, err := req.Execute(syscall.NETLINK_ROUTE, 0)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// LinkSetVfTrust enables/disables trust state on a vf for the link.
|
||||||
|
// Equivalent to: `ip link set $link vf $vf trust $state`
|
||||||
|
func LinkSetVfTrust(link Link, vf int, state bool) error {
|
||||||
|
return pkgHandle.LinkSetVfTrust(link, vf, state)
|
||||||
|
}
|
||||||
|
|
||||||
|
// LinkSetVfTrust enables/disables trust state on a vf for the link.
|
||||||
|
// Equivalent to: `ip link set $link vf $vf trust $state`
|
||||||
|
func (h *Handle) LinkSetVfTrust(link Link, vf int, state bool) error {
|
||||||
|
var setting uint32
|
||||||
|
base := link.Attrs()
|
||||||
|
h.ensureIndex(base)
|
||||||
|
req := h.newNetlinkRequest(syscall.RTM_SETLINK, syscall.NLM_F_ACK)
|
||||||
|
|
||||||
|
msg := nl.NewIfInfomsg(syscall.AF_UNSPEC)
|
||||||
|
msg.Index = int32(base.Index)
|
||||||
|
req.AddData(msg)
|
||||||
|
|
||||||
|
data := nl.NewRtAttr(nl.IFLA_VFINFO_LIST, nil)
|
||||||
|
info := nl.NewRtAttrChild(data, nl.IFLA_VF_INFO, nil)
|
||||||
|
if state {
|
||||||
|
setting = 1
|
||||||
|
}
|
||||||
|
vfmsg := nl.VfTrust{
|
||||||
|
Vf: uint32(vf),
|
||||||
|
Setting: setting,
|
||||||
|
}
|
||||||
|
nl.NewRtAttrChild(info, nl.IFLA_VF_TRUST, vfmsg.Serialize())
|
||||||
|
req.AddData(data)
|
||||||
|
|
||||||
|
_, err := req.Execute(syscall.NETLINK_ROUTE, 0)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
// LinkSetMaster sets the master of the link device.
|
// LinkSetMaster sets the master of the link device.
|
||||||
// Equivalent to: `ip link set $link master $master`
|
// Equivalent to: `ip link set $link master $master`
|
||||||
func LinkSetMaster(link Link, master *Bridge) error {
|
func LinkSetMaster(link Link, master *Bridge) error {
|
||||||
|
@ -500,6 +568,12 @@ func (h *Handle) LinkSetNsFd(link Link, fd int) error {
|
||||||
// LinkSetXdpFd adds a bpf function to the driver. The fd must be a bpf
|
// LinkSetXdpFd adds a bpf function to the driver. The fd must be a bpf
|
||||||
// program loaded with bpf(type=BPF_PROG_TYPE_XDP)
|
// program loaded with bpf(type=BPF_PROG_TYPE_XDP)
|
||||||
func LinkSetXdpFd(link Link, fd int) error {
|
func LinkSetXdpFd(link Link, fd int) error {
|
||||||
|
return LinkSetXdpFdWithFlags(link, fd, 0)
|
||||||
|
}
|
||||||
|
|
||||||
|
// LinkSetXdpFdWithFlags adds a bpf function to the driver with the given
|
||||||
|
// options. The fd must be a bpf program loaded with bpf(type=BPF_PROG_TYPE_XDP)
|
||||||
|
func LinkSetXdpFdWithFlags(link Link, fd, flags int) error {
|
||||||
base := link.Attrs()
|
base := link.Attrs()
|
||||||
ensureIndex(base)
|
ensureIndex(base)
|
||||||
req := nl.NewNetlinkRequest(syscall.RTM_SETLINK, syscall.NLM_F_ACK)
|
req := nl.NewNetlinkRequest(syscall.RTM_SETLINK, syscall.NLM_F_ACK)
|
||||||
|
@ -508,7 +582,7 @@ func LinkSetXdpFd(link Link, fd int) error {
|
||||||
msg.Index = int32(base.Index)
|
msg.Index = int32(base.Index)
|
||||||
req.AddData(msg)
|
req.AddData(msg)
|
||||||
|
|
||||||
addXdpAttrs(&LinkXdp{Fd: fd}, req)
|
addXdpAttrs(&LinkXdp{Fd: fd, Flags: uint32(flags)}, req)
|
||||||
|
|
||||||
_, err := req.Execute(syscall.NETLINK_ROUTE, 0)
|
_, err := req.Execute(syscall.NETLINK_ROUTE, 0)
|
||||||
return err
|
return err
|
||||||
|
@ -528,7 +602,13 @@ type vxlanPortRange struct {
|
||||||
|
|
||||||
func addVxlanAttrs(vxlan *Vxlan, linkInfo *nl.RtAttr) {
|
func addVxlanAttrs(vxlan *Vxlan, linkInfo *nl.RtAttr) {
|
||||||
data := nl.NewRtAttrChild(linkInfo, nl.IFLA_INFO_DATA, nil)
|
data := nl.NewRtAttrChild(linkInfo, nl.IFLA_INFO_DATA, nil)
|
||||||
|
|
||||||
|
if vxlan.FlowBased {
|
||||||
|
vxlan.VxlanId = 0
|
||||||
|
}
|
||||||
|
|
||||||
nl.NewRtAttrChild(data, nl.IFLA_VXLAN_ID, nl.Uint32Attr(uint32(vxlan.VxlanId)))
|
nl.NewRtAttrChild(data, nl.IFLA_VXLAN_ID, nl.Uint32Attr(uint32(vxlan.VxlanId)))
|
||||||
|
|
||||||
if vxlan.VtepDevIndex != 0 {
|
if vxlan.VtepDevIndex != 0 {
|
||||||
nl.NewRtAttrChild(data, nl.IFLA_VXLAN_LINK, nl.Uint32Attr(uint32(vxlan.VtepDevIndex)))
|
nl.NewRtAttrChild(data, nl.IFLA_VXLAN_LINK, nl.Uint32Attr(uint32(vxlan.VtepDevIndex)))
|
||||||
}
|
}
|
||||||
|
@ -569,6 +649,9 @@ func addVxlanAttrs(vxlan *Vxlan, linkInfo *nl.RtAttr) {
|
||||||
if vxlan.GBP {
|
if vxlan.GBP {
|
||||||
nl.NewRtAttrChild(data, nl.IFLA_VXLAN_GBP, []byte{})
|
nl.NewRtAttrChild(data, nl.IFLA_VXLAN_GBP, []byte{})
|
||||||
}
|
}
|
||||||
|
if vxlan.FlowBased {
|
||||||
|
nl.NewRtAttrChild(data, nl.IFLA_VXLAN_FLOWBASED, boolAttr(vxlan.FlowBased))
|
||||||
|
}
|
||||||
if vxlan.NoAge {
|
if vxlan.NoAge {
|
||||||
nl.NewRtAttrChild(data, nl.IFLA_VXLAN_AGEING, nl.Uint32Attr(0))
|
nl.NewRtAttrChild(data, nl.IFLA_VXLAN_AGEING, nl.Uint32Attr(0))
|
||||||
} else if vxlan.Age > 0 {
|
} else if vxlan.Age > 0 {
|
||||||
|
@ -818,16 +901,17 @@ func (h *Handle) linkModify(link Link, flags int) error {
|
||||||
linkInfo := nl.NewRtAttr(syscall.IFLA_LINKINFO, nil)
|
linkInfo := nl.NewRtAttr(syscall.IFLA_LINKINFO, nil)
|
||||||
nl.NewRtAttrChild(linkInfo, nl.IFLA_INFO_KIND, nl.NonZeroTerminated(link.Type()))
|
nl.NewRtAttrChild(linkInfo, nl.IFLA_INFO_KIND, nl.NonZeroTerminated(link.Type()))
|
||||||
|
|
||||||
if vlan, ok := link.(*Vlan); ok {
|
switch link := link.(type) {
|
||||||
|
case *Vlan:
|
||||||
b := make([]byte, 2)
|
b := make([]byte, 2)
|
||||||
native.PutUint16(b, uint16(vlan.VlanId))
|
native.PutUint16(b, uint16(link.VlanId))
|
||||||
data := nl.NewRtAttrChild(linkInfo, nl.IFLA_INFO_DATA, nil)
|
data := nl.NewRtAttrChild(linkInfo, nl.IFLA_INFO_DATA, nil)
|
||||||
nl.NewRtAttrChild(data, nl.IFLA_VLAN_ID, b)
|
nl.NewRtAttrChild(data, nl.IFLA_VLAN_ID, b)
|
||||||
} else if veth, ok := link.(*Veth); ok {
|
case *Veth:
|
||||||
data := nl.NewRtAttrChild(linkInfo, nl.IFLA_INFO_DATA, nil)
|
data := nl.NewRtAttrChild(linkInfo, nl.IFLA_INFO_DATA, nil)
|
||||||
peer := nl.NewRtAttrChild(data, nl.VETH_INFO_PEER, nil)
|
peer := nl.NewRtAttrChild(data, nl.VETH_INFO_PEER, nil)
|
||||||
nl.NewIfInfomsgChild(peer, syscall.AF_UNSPEC)
|
nl.NewIfInfomsgChild(peer, syscall.AF_UNSPEC)
|
||||||
nl.NewRtAttrChild(peer, syscall.IFLA_IFNAME, nl.ZeroTerminated(veth.PeerName))
|
nl.NewRtAttrChild(peer, syscall.IFLA_IFNAME, nl.ZeroTerminated(link.PeerName))
|
||||||
if base.TxQLen >= 0 {
|
if base.TxQLen >= 0 {
|
||||||
nl.NewRtAttrChild(peer, syscall.IFLA_TXQLEN, nl.Uint32Attr(uint32(base.TxQLen)))
|
nl.NewRtAttrChild(peer, syscall.IFLA_TXQLEN, nl.Uint32Attr(uint32(base.TxQLen)))
|
||||||
}
|
}
|
||||||
|
@ -835,35 +919,37 @@ func (h *Handle) linkModify(link Link, flags int) error {
|
||||||
nl.NewRtAttrChild(peer, syscall.IFLA_MTU, nl.Uint32Attr(uint32(base.MTU)))
|
nl.NewRtAttrChild(peer, syscall.IFLA_MTU, nl.Uint32Attr(uint32(base.MTU)))
|
||||||
}
|
}
|
||||||
|
|
||||||
} else if vxlan, ok := link.(*Vxlan); ok {
|
case *Vxlan:
|
||||||
addVxlanAttrs(vxlan, linkInfo)
|
addVxlanAttrs(link, linkInfo)
|
||||||
} else if bond, ok := link.(*Bond); ok {
|
case *Bond:
|
||||||
addBondAttrs(bond, linkInfo)
|
addBondAttrs(link, linkInfo)
|
||||||
} else if ipv, ok := link.(*IPVlan); ok {
|
case *IPVlan:
|
||||||
data := nl.NewRtAttrChild(linkInfo, nl.IFLA_INFO_DATA, nil)
|
data := nl.NewRtAttrChild(linkInfo, nl.IFLA_INFO_DATA, nil)
|
||||||
nl.NewRtAttrChild(data, nl.IFLA_IPVLAN_MODE, nl.Uint16Attr(uint16(ipv.Mode)))
|
nl.NewRtAttrChild(data, nl.IFLA_IPVLAN_MODE, nl.Uint16Attr(uint16(link.Mode)))
|
||||||
} else if macv, ok := link.(*Macvlan); ok {
|
case *Macvlan:
|
||||||
if macv.Mode != MACVLAN_MODE_DEFAULT {
|
if link.Mode != MACVLAN_MODE_DEFAULT {
|
||||||
data := nl.NewRtAttrChild(linkInfo, nl.IFLA_INFO_DATA, nil)
|
data := nl.NewRtAttrChild(linkInfo, nl.IFLA_INFO_DATA, nil)
|
||||||
nl.NewRtAttrChild(data, nl.IFLA_MACVLAN_MODE, nl.Uint32Attr(macvlanModes[macv.Mode]))
|
nl.NewRtAttrChild(data, nl.IFLA_MACVLAN_MODE, nl.Uint32Attr(macvlanModes[link.Mode]))
|
||||||
}
|
}
|
||||||
} else if macv, ok := link.(*Macvtap); ok {
|
case *Macvtap:
|
||||||
if macv.Mode != MACVLAN_MODE_DEFAULT {
|
if link.Mode != MACVLAN_MODE_DEFAULT {
|
||||||
data := nl.NewRtAttrChild(linkInfo, nl.IFLA_INFO_DATA, nil)
|
data := nl.NewRtAttrChild(linkInfo, nl.IFLA_INFO_DATA, nil)
|
||||||
nl.NewRtAttrChild(data, nl.IFLA_MACVLAN_MODE, nl.Uint32Attr(macvlanModes[macv.Mode]))
|
nl.NewRtAttrChild(data, nl.IFLA_MACVLAN_MODE, nl.Uint32Attr(macvlanModes[link.Mode]))
|
||||||
}
|
}
|
||||||
} else if gretap, ok := link.(*Gretap); ok {
|
case *Gretap:
|
||||||
addGretapAttrs(gretap, linkInfo)
|
addGretapAttrs(link, linkInfo)
|
||||||
} else if iptun, ok := link.(*Iptun); ok {
|
case *Iptun:
|
||||||
addIptunAttrs(iptun, linkInfo)
|
addIptunAttrs(link, linkInfo)
|
||||||
} else if vti, ok := link.(*Vti); ok {
|
case *Gretun:
|
||||||
addVtiAttrs(vti, linkInfo)
|
addGretunAttrs(link, linkInfo)
|
||||||
} else if vrf, ok := link.(*Vrf); ok {
|
case *Vti:
|
||||||
addVrfAttrs(vrf, linkInfo)
|
addVtiAttrs(link, linkInfo)
|
||||||
} else if bridge, ok := link.(*Bridge); ok {
|
case *Vrf:
|
||||||
addBridgeAttrs(bridge, linkInfo)
|
addVrfAttrs(link, linkInfo)
|
||||||
} else if gtp, ok := link.(*GTP); ok {
|
case *Bridge:
|
||||||
addGTPAttrs(gtp, linkInfo)
|
addBridgeAttrs(link, linkInfo)
|
||||||
|
case *GTP:
|
||||||
|
addGTPAttrs(link, linkInfo)
|
||||||
}
|
}
|
||||||
|
|
||||||
req.AddData(linkInfo)
|
req.AddData(linkInfo)
|
||||||
|
@ -1093,6 +1179,8 @@ func LinkDeserialize(hdr *syscall.NlMsghdr, m []byte) (Link, error) {
|
||||||
link = &Gretap{}
|
link = &Gretap{}
|
||||||
case "ipip":
|
case "ipip":
|
||||||
link = &Iptun{}
|
link = &Iptun{}
|
||||||
|
case "gre":
|
||||||
|
link = &Gretun{}
|
||||||
case "vti":
|
case "vti":
|
||||||
link = &Vti{}
|
link = &Vti{}
|
||||||
case "vrf":
|
case "vrf":
|
||||||
|
@ -1124,6 +1212,8 @@ func LinkDeserialize(hdr *syscall.NlMsghdr, m []byte) (Link, error) {
|
||||||
parseGretapData(link, data)
|
parseGretapData(link, data)
|
||||||
case "ipip":
|
case "ipip":
|
||||||
parseIptunData(link, data)
|
parseIptunData(link, data)
|
||||||
|
case "gre":
|
||||||
|
parseGretunData(link, data)
|
||||||
case "vti":
|
case "vti":
|
||||||
parseVtiData(link, data)
|
parseVtiData(link, data)
|
||||||
case "vrf":
|
case "vrf":
|
||||||
|
@ -1178,6 +1268,8 @@ func LinkDeserialize(hdr *syscall.NlMsghdr, m []byte) (Link, error) {
|
||||||
}
|
}
|
||||||
case syscall.IFLA_OPERSTATE:
|
case syscall.IFLA_OPERSTATE:
|
||||||
base.OperState = LinkOperState(uint8(attr.Value[0]))
|
base.OperState = LinkOperState(uint8(attr.Value[0]))
|
||||||
|
case nl.IFLA_LINK_NETNSID:
|
||||||
|
base.NetNsID = int(native.Uint32(attr.Value[0:4]))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1239,16 +1331,34 @@ type LinkUpdate struct {
|
||||||
// LinkSubscribe takes a chan down which notifications will be sent
|
// LinkSubscribe takes a chan down which notifications will be sent
|
||||||
// when links change. Close the 'done' chan to stop subscription.
|
// when links change. Close the 'done' chan to stop subscription.
|
||||||
func LinkSubscribe(ch chan<- LinkUpdate, done <-chan struct{}) error {
|
func LinkSubscribe(ch chan<- LinkUpdate, done <-chan struct{}) error {
|
||||||
return linkSubscribe(netns.None(), netns.None(), ch, done)
|
return linkSubscribeAt(netns.None(), netns.None(), ch, done, nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
// LinkSubscribeAt works like LinkSubscribe plus it allows the caller
|
// LinkSubscribeAt works like LinkSubscribe plus it allows the caller
|
||||||
// to choose the network namespace in which to subscribe (ns).
|
// to choose the network namespace in which to subscribe (ns).
|
||||||
func LinkSubscribeAt(ns netns.NsHandle, ch chan<- LinkUpdate, done <-chan struct{}) error {
|
func LinkSubscribeAt(ns netns.NsHandle, ch chan<- LinkUpdate, done <-chan struct{}) error {
|
||||||
return linkSubscribe(ns, netns.None(), ch, done)
|
return linkSubscribeAt(ns, netns.None(), ch, done, nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
func linkSubscribe(newNs, curNs netns.NsHandle, ch chan<- LinkUpdate, done <-chan struct{}) error {
|
// LinkSubscribeOptions contains a set of options to use with
|
||||||
|
// LinkSubscribeWithOptions.
|
||||||
|
type LinkSubscribeOptions struct {
|
||||||
|
Namespace *netns.NsHandle
|
||||||
|
ErrorCallback func(error)
|
||||||
|
}
|
||||||
|
|
||||||
|
// LinkSubscribeWithOptions work like LinkSubscribe but enable to
|
||||||
|
// provide additional options to modify the behavior. Currently, the
|
||||||
|
// namespace can be provided as well as an error callback.
|
||||||
|
func LinkSubscribeWithOptions(ch chan<- LinkUpdate, done <-chan struct{}, options LinkSubscribeOptions) error {
|
||||||
|
if options.Namespace == nil {
|
||||||
|
none := netns.None()
|
||||||
|
options.Namespace = &none
|
||||||
|
}
|
||||||
|
return linkSubscribeAt(*options.Namespace, netns.None(), ch, done, options.ErrorCallback)
|
||||||
|
}
|
||||||
|
|
||||||
|
func linkSubscribeAt(newNs, curNs netns.NsHandle, ch chan<- LinkUpdate, done <-chan struct{}, cberr func(error)) error {
|
||||||
s, err := nl.SubscribeAt(newNs, curNs, syscall.NETLINK_ROUTE, syscall.RTNLGRP_LINK)
|
s, err := nl.SubscribeAt(newNs, curNs, syscall.NETLINK_ROUTE, syscall.RTNLGRP_LINK)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
@ -1264,12 +1374,18 @@ func linkSubscribe(newNs, curNs netns.NsHandle, ch chan<- LinkUpdate, done <-cha
|
||||||
for {
|
for {
|
||||||
msgs, err := s.Receive()
|
msgs, err := s.Receive()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
if cberr != nil {
|
||||||
|
cberr(err)
|
||||||
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
for _, m := range msgs {
|
for _, m := range msgs {
|
||||||
ifmsg := nl.DeserializeIfInfomsg(m.Data)
|
ifmsg := nl.DeserializeIfInfomsg(m.Data)
|
||||||
link, err := LinkDeserialize(&m.Header, m.Data)
|
link, err := LinkDeserialize(&m.Header, m.Data)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
if cberr != nil {
|
||||||
|
cberr(err)
|
||||||
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
ch <- LinkUpdate{IfInfomsg: *ifmsg, Header: m.Header, Link: link}
|
ch <- LinkUpdate{IfInfomsg: *ifmsg, Header: m.Header, Link: link}
|
||||||
|
@ -1363,6 +1479,33 @@ func (h *Handle) setProtinfoAttr(link Link, mode bool, attr int) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// LinkSetTxQLen sets the transaction queue length for the link.
|
||||||
|
// Equivalent to: `ip link set $link txqlen $qlen`
|
||||||
|
func LinkSetTxQLen(link Link, qlen int) error {
|
||||||
|
return pkgHandle.LinkSetTxQLen(link, qlen)
|
||||||
|
}
|
||||||
|
|
||||||
|
// LinkSetTxQLen sets the transaction queue length for the link.
|
||||||
|
// Equivalent to: `ip link set $link txqlen $qlen`
|
||||||
|
func (h *Handle) LinkSetTxQLen(link Link, qlen int) error {
|
||||||
|
base := link.Attrs()
|
||||||
|
h.ensureIndex(base)
|
||||||
|
req := h.newNetlinkRequest(syscall.RTM_SETLINK, syscall.NLM_F_ACK)
|
||||||
|
|
||||||
|
msg := nl.NewIfInfomsg(syscall.AF_UNSPEC)
|
||||||
|
msg.Index = int32(base.Index)
|
||||||
|
req.AddData(msg)
|
||||||
|
|
||||||
|
b := make([]byte, 4)
|
||||||
|
native.PutUint32(b, uint32(qlen))
|
||||||
|
|
||||||
|
data := nl.NewRtAttr(syscall.IFLA_TXQLEN, b)
|
||||||
|
req.AddData(data)
|
||||||
|
|
||||||
|
_, err := req.Execute(syscall.NETLINK_ROUTE, 0)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
func parseVlanData(link Link, data []syscall.NetlinkRouteAttr) {
|
func parseVlanData(link Link, data []syscall.NetlinkRouteAttr) {
|
||||||
vlan := link.(*Vlan)
|
vlan := link.(*Vlan)
|
||||||
for _, datum := range data {
|
for _, datum := range data {
|
||||||
|
@ -1407,6 +1550,8 @@ func parseVxlanData(link Link, data []syscall.NetlinkRouteAttr) {
|
||||||
vxlan.UDPCSum = int8(datum.Value[0]) != 0
|
vxlan.UDPCSum = int8(datum.Value[0]) != 0
|
||||||
case nl.IFLA_VXLAN_GBP:
|
case nl.IFLA_VXLAN_GBP:
|
||||||
vxlan.GBP = true
|
vxlan.GBP = true
|
||||||
|
case nl.IFLA_VXLAN_FLOWBASED:
|
||||||
|
vxlan.FlowBased = int8(datum.Value[0]) != 0
|
||||||
case nl.IFLA_VXLAN_AGEING:
|
case nl.IFLA_VXLAN_AGEING:
|
||||||
vxlan.Age = int(native.Uint32(datum.Value[0:4]))
|
vxlan.Age = int(native.Uint32(datum.Value[0:4]))
|
||||||
vxlan.NoAge = vxlan.Age == 0
|
vxlan.NoAge = vxlan.Age == 0
|
||||||
|
@ -1547,6 +1692,12 @@ func linkFlags(rawFlags uint32) net.Flags {
|
||||||
func addGretapAttrs(gretap *Gretap, linkInfo *nl.RtAttr) {
|
func addGretapAttrs(gretap *Gretap, linkInfo *nl.RtAttr) {
|
||||||
data := nl.NewRtAttrChild(linkInfo, nl.IFLA_INFO_DATA, nil)
|
data := nl.NewRtAttrChild(linkInfo, nl.IFLA_INFO_DATA, nil)
|
||||||
|
|
||||||
|
if gretap.FlowBased {
|
||||||
|
// In flow based mode, no other attributes need to be configured
|
||||||
|
nl.NewRtAttrChild(data, nl.IFLA_GRE_COLLECT_METADATA, boolAttr(gretap.FlowBased))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
ip := gretap.Local.To4()
|
ip := gretap.Local.To4()
|
||||||
if ip != nil {
|
if ip != nil {
|
||||||
nl.NewRtAttrChild(data, nl.IFLA_GRE_LOCAL, []byte(ip))
|
nl.NewRtAttrChild(data, nl.IFLA_GRE_LOCAL, []byte(ip))
|
||||||
|
@ -1613,6 +1764,69 @@ func parseGretapData(link Link, data []syscall.NetlinkRouteAttr) {
|
||||||
gre.EncapType = native.Uint16(datum.Value[0:2])
|
gre.EncapType = native.Uint16(datum.Value[0:2])
|
||||||
case nl.IFLA_GRE_ENCAP_FLAGS:
|
case nl.IFLA_GRE_ENCAP_FLAGS:
|
||||||
gre.EncapFlags = native.Uint16(datum.Value[0:2])
|
gre.EncapFlags = native.Uint16(datum.Value[0:2])
|
||||||
|
case nl.IFLA_GRE_COLLECT_METADATA:
|
||||||
|
gre.FlowBased = int8(datum.Value[0]) != 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func addGretunAttrs(gre *Gretun, linkInfo *nl.RtAttr) {
|
||||||
|
data := nl.NewRtAttrChild(linkInfo, nl.IFLA_INFO_DATA, nil)
|
||||||
|
|
||||||
|
ip := gre.Local.To4()
|
||||||
|
if ip != nil {
|
||||||
|
nl.NewRtAttrChild(data, nl.IFLA_GRE_LOCAL, []byte(ip))
|
||||||
|
}
|
||||||
|
ip = gre.Remote.To4()
|
||||||
|
if ip != nil {
|
||||||
|
nl.NewRtAttrChild(data, nl.IFLA_GRE_REMOTE, []byte(ip))
|
||||||
|
}
|
||||||
|
|
||||||
|
if gre.IKey != 0 {
|
||||||
|
nl.NewRtAttrChild(data, nl.IFLA_GRE_IKEY, htonl(gre.IKey))
|
||||||
|
gre.IFlags |= uint16(nl.GRE_KEY)
|
||||||
|
}
|
||||||
|
|
||||||
|
if gre.OKey != 0 {
|
||||||
|
nl.NewRtAttrChild(data, nl.IFLA_GRE_OKEY, htonl(gre.OKey))
|
||||||
|
gre.OFlags |= uint16(nl.GRE_KEY)
|
||||||
|
}
|
||||||
|
|
||||||
|
nl.NewRtAttrChild(data, nl.IFLA_GRE_IFLAGS, htons(gre.IFlags))
|
||||||
|
nl.NewRtAttrChild(data, nl.IFLA_GRE_OFLAGS, htons(gre.OFlags))
|
||||||
|
|
||||||
|
if gre.Link != 0 {
|
||||||
|
nl.NewRtAttrChild(data, nl.IFLA_GRE_LINK, nl.Uint32Attr(gre.Link))
|
||||||
|
}
|
||||||
|
|
||||||
|
nl.NewRtAttrChild(data, nl.IFLA_GRE_PMTUDISC, nl.Uint8Attr(gre.PMtuDisc))
|
||||||
|
nl.NewRtAttrChild(data, nl.IFLA_GRE_TTL, nl.Uint8Attr(gre.Ttl))
|
||||||
|
nl.NewRtAttrChild(data, nl.IFLA_GRE_TOS, nl.Uint8Attr(gre.Tos))
|
||||||
|
}
|
||||||
|
|
||||||
|
func parseGretunData(link Link, data []syscall.NetlinkRouteAttr) {
|
||||||
|
gre := link.(*Gretun)
|
||||||
|
for _, datum := range data {
|
||||||
|
switch datum.Attr.Type {
|
||||||
|
case nl.IFLA_GRE_OKEY:
|
||||||
|
gre.IKey = ntohl(datum.Value[0:4])
|
||||||
|
case nl.IFLA_GRE_IKEY:
|
||||||
|
gre.OKey = ntohl(datum.Value[0:4])
|
||||||
|
case nl.IFLA_GRE_LOCAL:
|
||||||
|
gre.Local = net.IP(datum.Value[0:4])
|
||||||
|
case nl.IFLA_GRE_REMOTE:
|
||||||
|
gre.Remote = net.IP(datum.Value[0:4])
|
||||||
|
case nl.IFLA_GRE_IFLAGS:
|
||||||
|
gre.IFlags = ntohs(datum.Value[0:2])
|
||||||
|
case nl.IFLA_GRE_OFLAGS:
|
||||||
|
gre.OFlags = ntohs(datum.Value[0:2])
|
||||||
|
|
||||||
|
case nl.IFLA_GRE_TTL:
|
||||||
|
gre.Ttl = uint8(datum.Value[0])
|
||||||
|
case nl.IFLA_GRE_TOS:
|
||||||
|
gre.Tos = uint8(datum.Value[0])
|
||||||
|
case nl.IFLA_GRE_PMTUDISC:
|
||||||
|
gre.PMtuDisc = uint8(datum.Value[0])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1630,8 +1844,10 @@ func addXdpAttrs(xdp *LinkXdp, req *nl.NetlinkRequest) {
|
||||||
b := make([]byte, 4)
|
b := make([]byte, 4)
|
||||||
native.PutUint32(b, uint32(xdp.Fd))
|
native.PutUint32(b, uint32(xdp.Fd))
|
||||||
nl.NewRtAttrChild(attrs, nl.IFLA_XDP_FD, b)
|
nl.NewRtAttrChild(attrs, nl.IFLA_XDP_FD, b)
|
||||||
native.PutUint32(b, xdp.Flags)
|
if xdp.Flags != 0 {
|
||||||
nl.NewRtAttrChild(attrs, nl.IFLA_XDP_FLAGS, b)
|
native.PutUint32(b, xdp.Flags)
|
||||||
|
nl.NewRtAttrChild(attrs, nl.IFLA_XDP_FLAGS, b)
|
||||||
|
}
|
||||||
req.AddData(attrs)
|
req.AddData(attrs)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1649,6 +1865,8 @@ func parseLinkXdp(data []byte) (*LinkXdp, error) {
|
||||||
xdp.Attached = attr.Value[0] != 0
|
xdp.Attached = attr.Value[0] != 0
|
||||||
case nl.IFLA_XDP_FLAGS:
|
case nl.IFLA_XDP_FLAGS:
|
||||||
xdp.Flags = native.Uint32(attr.Value[0:4])
|
xdp.Flags = native.Uint32(attr.Value[0:4])
|
||||||
|
case nl.IFLA_XDP_PROG_ID:
|
||||||
|
xdp.ProgId = native.Uint32(attr.Value[0:4])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return xdp, nil
|
return xdp, nil
|
||||||
|
|
1
libnetwork/vendor/github.com/vishvananda/netlink/neigh.go
generated
vendored
1
libnetwork/vendor/github.com/vishvananda/netlink/neigh.go
generated
vendored
|
@ -14,6 +14,7 @@ type Neigh struct {
|
||||||
Flags int
|
Flags int
|
||||||
IP net.IP
|
IP net.IP
|
||||||
HardwareAddr net.HardwareAddr
|
HardwareAddr net.HardwareAddr
|
||||||
|
LLIPAddr net.IP //Used in the case of NHRP
|
||||||
}
|
}
|
||||||
|
|
||||||
// String returns $ip/$hwaddr $label
|
// String returns $ip/$hwaddr $label
|
||||||
|
|
29
libnetwork/vendor/github.com/vishvananda/netlink/neigh_linux.go
generated
vendored
29
libnetwork/vendor/github.com/vishvananda/netlink/neigh_linux.go
generated
vendored
|
@ -128,6 +128,7 @@ func (h *Handle) NeighDel(neigh *Neigh) error {
|
||||||
|
|
||||||
func neighHandle(neigh *Neigh, req *nl.NetlinkRequest) error {
|
func neighHandle(neigh *Neigh, req *nl.NetlinkRequest) error {
|
||||||
var family int
|
var family int
|
||||||
|
|
||||||
if neigh.Family > 0 {
|
if neigh.Family > 0 {
|
||||||
family = neigh.Family
|
family = neigh.Family
|
||||||
} else {
|
} else {
|
||||||
|
@ -151,7 +152,10 @@ func neighHandle(neigh *Neigh, req *nl.NetlinkRequest) error {
|
||||||
dstData := nl.NewRtAttr(NDA_DST, ipData)
|
dstData := nl.NewRtAttr(NDA_DST, ipData)
|
||||||
req.AddData(dstData)
|
req.AddData(dstData)
|
||||||
|
|
||||||
if neigh.Flags != NTF_PROXY || neigh.HardwareAddr != nil {
|
if neigh.LLIPAddr != nil {
|
||||||
|
llIPData := nl.NewRtAttr(NDA_LLADDR, neigh.LLIPAddr.To4())
|
||||||
|
req.AddData(llIPData)
|
||||||
|
} else if neigh.Flags != NTF_PROXY || neigh.HardwareAddr != nil {
|
||||||
hwData := nl.NewRtAttr(NDA_LLADDR, []byte(neigh.HardwareAddr))
|
hwData := nl.NewRtAttr(NDA_LLADDR, []byte(neigh.HardwareAddr))
|
||||||
req.AddData(hwData)
|
req.AddData(hwData)
|
||||||
}
|
}
|
||||||
|
@ -237,12 +241,33 @@ func NeighDeserialize(m []byte) (*Neigh, error) {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// This should be cached for perfomance
|
||||||
|
// once per table dump
|
||||||
|
link, err := LinkByIndex(neigh.LinkIndex)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
encapType := link.Attrs().EncapType
|
||||||
|
|
||||||
for _, attr := range attrs {
|
for _, attr := range attrs {
|
||||||
switch attr.Attr.Type {
|
switch attr.Attr.Type {
|
||||||
case NDA_DST:
|
case NDA_DST:
|
||||||
neigh.IP = net.IP(attr.Value)
|
neigh.IP = net.IP(attr.Value)
|
||||||
case NDA_LLADDR:
|
case NDA_LLADDR:
|
||||||
neigh.HardwareAddr = net.HardwareAddr(attr.Value)
|
// BUG: Is this a bug in the netlink library?
|
||||||
|
// #define RTA_LENGTH(len) (RTA_ALIGN(sizeof(struct rtattr)) + (len))
|
||||||
|
// #define RTA_PAYLOAD(rta) ((int)((rta)->rta_len) - RTA_LENGTH(0))
|
||||||
|
attrLen := attr.Attr.Len - syscall.SizeofRtAttr
|
||||||
|
if attrLen == 4 && (encapType == "ipip" ||
|
||||||
|
encapType == "sit" ||
|
||||||
|
encapType == "gre") {
|
||||||
|
neigh.LLIPAddr = net.IP(attr.Value)
|
||||||
|
} else if attrLen == 16 &&
|
||||||
|
encapType == "tunnel6" {
|
||||||
|
neigh.IP = net.IP(attr.Value)
|
||||||
|
} else {
|
||||||
|
neigh.HardwareAddr = net.HardwareAddr(attr.Value)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
4
libnetwork/vendor/github.com/vishvananda/netlink/netlink_unspecified.go
generated
vendored
4
libnetwork/vendor/github.com/vishvananda/netlink/netlink_unspecified.go
generated
vendored
|
@ -108,6 +108,10 @@ func LinkSetFlood(link Link, mode bool) error {
|
||||||
return ErrNotImplemented
|
return ErrNotImplemented
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func LinkSetTxQLen(link Link, qlen int) error {
|
||||||
|
return ErrNotImplemented
|
||||||
|
}
|
||||||
|
|
||||||
func LinkAdd(link Link) error {
|
func LinkAdd(link Link) error {
|
||||||
return ErrNotImplemented
|
return ErrNotImplemented
|
||||||
}
|
}
|
||||||
|
|
74
libnetwork/vendor/github.com/vishvananda/netlink/nl/bridge_linux.go
generated
vendored
Normal file
74
libnetwork/vendor/github.com/vishvananda/netlink/nl/bridge_linux.go
generated
vendored
Normal file
|
@ -0,0 +1,74 @@
|
||||||
|
package nl
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"unsafe"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
SizeofBridgeVlanInfo = 0x04
|
||||||
|
)
|
||||||
|
|
||||||
|
/* Bridge Flags */
|
||||||
|
const (
|
||||||
|
BRIDGE_FLAGS_MASTER = iota /* Bridge command to/from master */
|
||||||
|
BRIDGE_FLAGS_SELF /* Bridge command to/from lowerdev */
|
||||||
|
)
|
||||||
|
|
||||||
|
/* Bridge management nested attributes
|
||||||
|
* [IFLA_AF_SPEC] = {
|
||||||
|
* [IFLA_BRIDGE_FLAGS]
|
||||||
|
* [IFLA_BRIDGE_MODE]
|
||||||
|
* [IFLA_BRIDGE_VLAN_INFO]
|
||||||
|
* }
|
||||||
|
*/
|
||||||
|
const (
|
||||||
|
IFLA_BRIDGE_FLAGS = iota
|
||||||
|
IFLA_BRIDGE_MODE
|
||||||
|
IFLA_BRIDGE_VLAN_INFO
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
BRIDGE_VLAN_INFO_MASTER = 1 << iota
|
||||||
|
BRIDGE_VLAN_INFO_PVID
|
||||||
|
BRIDGE_VLAN_INFO_UNTAGGED
|
||||||
|
BRIDGE_VLAN_INFO_RANGE_BEGIN
|
||||||
|
BRIDGE_VLAN_INFO_RANGE_END
|
||||||
|
)
|
||||||
|
|
||||||
|
// struct bridge_vlan_info {
|
||||||
|
// __u16 flags;
|
||||||
|
// __u16 vid;
|
||||||
|
// };
|
||||||
|
|
||||||
|
type BridgeVlanInfo struct {
|
||||||
|
Flags uint16
|
||||||
|
Vid uint16
|
||||||
|
}
|
||||||
|
|
||||||
|
func (b *BridgeVlanInfo) Serialize() []byte {
|
||||||
|
return (*(*[SizeofBridgeVlanInfo]byte)(unsafe.Pointer(b)))[:]
|
||||||
|
}
|
||||||
|
|
||||||
|
func DeserializeBridgeVlanInfo(b []byte) *BridgeVlanInfo {
|
||||||
|
return (*BridgeVlanInfo)(unsafe.Pointer(&b[0:SizeofBridgeVlanInfo][0]))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (b *BridgeVlanInfo) PortVID() bool {
|
||||||
|
return b.Flags&BRIDGE_VLAN_INFO_PVID > 0
|
||||||
|
}
|
||||||
|
|
||||||
|
func (b *BridgeVlanInfo) EngressUntag() bool {
|
||||||
|
return b.Flags&BRIDGE_VLAN_INFO_UNTAGGED > 0
|
||||||
|
}
|
||||||
|
|
||||||
|
func (b *BridgeVlanInfo) String() string {
|
||||||
|
return fmt.Sprintf("%+v", *b)
|
||||||
|
}
|
||||||
|
|
||||||
|
/* New extended info filters for IFLA_EXT_MASK */
|
||||||
|
const (
|
||||||
|
RTEXT_FILTER_VF = 1 << iota
|
||||||
|
RTEXT_FILTER_BRVLAN
|
||||||
|
RTEXT_FILTER_BRVLAN_COMPRESSED
|
||||||
|
)
|
4
libnetwork/vendor/github.com/vishvananda/netlink/nl/conntrack_linux.go
generated
vendored
4
libnetwork/vendor/github.com/vishvananda/netlink/nl/conntrack_linux.go
generated
vendored
|
@ -79,8 +79,8 @@ const (
|
||||||
CTA_TUPLE_ORIG = 1
|
CTA_TUPLE_ORIG = 1
|
||||||
CTA_TUPLE_REPLY = 2
|
CTA_TUPLE_REPLY = 2
|
||||||
CTA_STATUS = 3
|
CTA_STATUS = 3
|
||||||
CTA_TIMEOUT = 8
|
CTA_TIMEOUT = 7
|
||||||
CTA_MARK = 9
|
CTA_MARK = 8
|
||||||
CTA_PROTOINFO = 4
|
CTA_PROTOINFO = 4
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
36
libnetwork/vendor/github.com/vishvananda/netlink/nl/link_linux.go
generated
vendored
36
libnetwork/vendor/github.com/vishvananda/netlink/nl/link_linux.go
generated
vendored
|
@ -231,7 +231,8 @@ const (
|
||||||
* on/off switch
|
* on/off switch
|
||||||
*/
|
*/
|
||||||
IFLA_VF_STATS /* network device statistics */
|
IFLA_VF_STATS /* network device statistics */
|
||||||
IFLA_VF_MAX = IFLA_VF_STATS
|
IFLA_VF_TRUST /* Trust state of VF */
|
||||||
|
IFLA_VF_MAX = IFLA_VF_TRUST
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
@ -259,6 +260,7 @@ const (
|
||||||
SizeofVfSpoofchk = 0x08
|
SizeofVfSpoofchk = 0x08
|
||||||
SizeofVfLinkState = 0x08
|
SizeofVfLinkState = 0x08
|
||||||
SizeofVfRssQueryEn = 0x08
|
SizeofVfRssQueryEn = 0x08
|
||||||
|
SizeofVfTrust = 0x08
|
||||||
)
|
)
|
||||||
|
|
||||||
// struct ifla_vf_mac {
|
// struct ifla_vf_mac {
|
||||||
|
@ -419,12 +421,42 @@ func (msg *VfRssQueryEn) Serialize() []byte {
|
||||||
return (*(*[SizeofVfRssQueryEn]byte)(unsafe.Pointer(msg)))[:]
|
return (*(*[SizeofVfRssQueryEn]byte)(unsafe.Pointer(msg)))[:]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// struct ifla_vf_trust {
|
||||||
|
// __u32 vf;
|
||||||
|
// __u32 setting;
|
||||||
|
// };
|
||||||
|
|
||||||
|
type VfTrust struct {
|
||||||
|
Vf uint32
|
||||||
|
Setting uint32
|
||||||
|
}
|
||||||
|
|
||||||
|
func (msg *VfTrust) Len() int {
|
||||||
|
return SizeofVfTrust
|
||||||
|
}
|
||||||
|
|
||||||
|
func DeserializeVfTrust(b []byte) *VfTrust {
|
||||||
|
return (*VfTrust)(unsafe.Pointer(&b[0:SizeofVfTrust][0]))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (msg *VfTrust) Serialize() []byte {
|
||||||
|
return (*(*[SizeofVfTrust]byte)(unsafe.Pointer(msg)))[:]
|
||||||
|
}
|
||||||
|
|
||||||
|
const (
|
||||||
|
XDP_FLAGS_UPDATE_IF_NOEXIST = 1 << iota
|
||||||
|
XDP_FLAGS_SKB_MODE
|
||||||
|
XDP_FLAGS_DRV_MODE
|
||||||
|
XDP_FLAGS_MASK = XDP_FLAGS_UPDATE_IF_NOEXIST | XDP_FLAGS_SKB_MODE | XDP_FLAGS_DRV_MODE
|
||||||
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
IFLA_XDP_UNSPEC = iota
|
IFLA_XDP_UNSPEC = iota
|
||||||
IFLA_XDP_FD /* fd of xdp program to attach, or -1 to remove */
|
IFLA_XDP_FD /* fd of xdp program to attach, or -1 to remove */
|
||||||
IFLA_XDP_ATTACHED /* read-only bool indicating if prog is attached */
|
IFLA_XDP_ATTACHED /* read-only bool indicating if prog is attached */
|
||||||
IFLA_XDP_FLAGS /* xdp prog related flags */
|
IFLA_XDP_FLAGS /* xdp prog related flags */
|
||||||
IFLA_XDP_MAX = IFLA_XDP_FLAGS
|
IFLA_XDP_PROG_ID /* xdp prog id */
|
||||||
|
IFLA_XDP_MAX = IFLA_XDP_PROG_ID
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
|
14
libnetwork/vendor/github.com/vishvananda/netlink/nl/nl_linux.go
generated
vendored
14
libnetwork/vendor/github.com/vishvananda/netlink/nl/nl_linux.go
generated
vendored
|
@ -621,6 +621,20 @@ func (s *NetlinkSocket) Receive() ([]syscall.NetlinkMessage, error) {
|
||||||
return syscall.ParseNetlinkMessage(rb)
|
return syscall.ParseNetlinkMessage(rb)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SetSendTimeout allows to set a send timeout on the socket
|
||||||
|
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
|
||||||
|
// remains stuck on a send on a closed fd
|
||||||
|
return syscall.SetsockoptTimeval(int(s.fd), syscall.SOL_SOCKET, syscall.SO_SNDTIMEO, timeout)
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetReceiveTimeout allows to set a receive timeout on the socket
|
||||||
|
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
|
||||||
|
// remains stuck on a recvmsg on a closed fd
|
||||||
|
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 := syscall.Getsockname(fd)
|
lsa, err := syscall.Getsockname(fd)
|
||||||
|
|
72
libnetwork/vendor/github.com/vishvananda/netlink/qdisc_linux.go
generated
vendored
72
libnetwork/vendor/github.com/vishvananda/netlink/qdisc_linux.go
generated
vendored
|
@ -160,71 +160,73 @@ func qdiscPayload(req *nl.NetlinkRequest, qdisc Qdisc) error {
|
||||||
req.AddData(nl.NewRtAttr(nl.TCA_KIND, nl.ZeroTerminated(qdisc.Type())))
|
req.AddData(nl.NewRtAttr(nl.TCA_KIND, nl.ZeroTerminated(qdisc.Type())))
|
||||||
|
|
||||||
options := nl.NewRtAttr(nl.TCA_OPTIONS, nil)
|
options := nl.NewRtAttr(nl.TCA_OPTIONS, nil)
|
||||||
if prio, ok := qdisc.(*Prio); ok {
|
|
||||||
|
switch qdisc := qdisc.(type) {
|
||||||
|
case *Prio:
|
||||||
tcmap := nl.TcPrioMap{
|
tcmap := nl.TcPrioMap{
|
||||||
Bands: int32(prio.Bands),
|
Bands: int32(qdisc.Bands),
|
||||||
Priomap: prio.PriorityMap,
|
Priomap: qdisc.PriorityMap,
|
||||||
}
|
}
|
||||||
options = nl.NewRtAttr(nl.TCA_OPTIONS, tcmap.Serialize())
|
options = nl.NewRtAttr(nl.TCA_OPTIONS, tcmap.Serialize())
|
||||||
} else if tbf, ok := qdisc.(*Tbf); ok {
|
case *Tbf:
|
||||||
opt := nl.TcTbfQopt{}
|
opt := nl.TcTbfQopt{}
|
||||||
opt.Rate.Rate = uint32(tbf.Rate)
|
opt.Rate.Rate = uint32(qdisc.Rate)
|
||||||
opt.Peakrate.Rate = uint32(tbf.Peakrate)
|
opt.Peakrate.Rate = uint32(qdisc.Peakrate)
|
||||||
opt.Limit = tbf.Limit
|
opt.Limit = qdisc.Limit
|
||||||
opt.Buffer = tbf.Buffer
|
opt.Buffer = qdisc.Buffer
|
||||||
nl.NewRtAttrChild(options, nl.TCA_TBF_PARMS, opt.Serialize())
|
nl.NewRtAttrChild(options, nl.TCA_TBF_PARMS, opt.Serialize())
|
||||||
if tbf.Rate >= uint64(1<<32) {
|
if qdisc.Rate >= uint64(1<<32) {
|
||||||
nl.NewRtAttrChild(options, nl.TCA_TBF_RATE64, nl.Uint64Attr(tbf.Rate))
|
nl.NewRtAttrChild(options, nl.TCA_TBF_RATE64, nl.Uint64Attr(qdisc.Rate))
|
||||||
}
|
}
|
||||||
if tbf.Peakrate >= uint64(1<<32) {
|
if qdisc.Peakrate >= uint64(1<<32) {
|
||||||
nl.NewRtAttrChild(options, nl.TCA_TBF_PRATE64, nl.Uint64Attr(tbf.Peakrate))
|
nl.NewRtAttrChild(options, nl.TCA_TBF_PRATE64, nl.Uint64Attr(qdisc.Peakrate))
|
||||||
}
|
}
|
||||||
if tbf.Peakrate > 0 {
|
if qdisc.Peakrate > 0 {
|
||||||
nl.NewRtAttrChild(options, nl.TCA_TBF_PBURST, nl.Uint32Attr(tbf.Minburst))
|
nl.NewRtAttrChild(options, nl.TCA_TBF_PBURST, nl.Uint32Attr(qdisc.Minburst))
|
||||||
}
|
}
|
||||||
} else if htb, ok := qdisc.(*Htb); ok {
|
case *Htb:
|
||||||
opt := nl.TcHtbGlob{}
|
opt := nl.TcHtbGlob{}
|
||||||
opt.Version = htb.Version
|
opt.Version = qdisc.Version
|
||||||
opt.Rate2Quantum = htb.Rate2Quantum
|
opt.Rate2Quantum = qdisc.Rate2Quantum
|
||||||
opt.Defcls = htb.Defcls
|
opt.Defcls = qdisc.Defcls
|
||||||
// TODO: Handle Debug properly. For now default to 0
|
// TODO: Handle Debug properly. For now default to 0
|
||||||
opt.Debug = htb.Debug
|
opt.Debug = qdisc.Debug
|
||||||
opt.DirectPkts = htb.DirectPkts
|
opt.DirectPkts = qdisc.DirectPkts
|
||||||
nl.NewRtAttrChild(options, nl.TCA_HTB_INIT, opt.Serialize())
|
nl.NewRtAttrChild(options, nl.TCA_HTB_INIT, opt.Serialize())
|
||||||
// nl.NewRtAttrChild(options, nl.TCA_HTB_DIRECT_QLEN, opt.Serialize())
|
// nl.NewRtAttrChild(options, nl.TCA_HTB_DIRECT_QLEN, opt.Serialize())
|
||||||
} else if netem, ok := qdisc.(*Netem); ok {
|
case *Netem:
|
||||||
opt := nl.TcNetemQopt{}
|
opt := nl.TcNetemQopt{}
|
||||||
opt.Latency = netem.Latency
|
opt.Latency = qdisc.Latency
|
||||||
opt.Limit = netem.Limit
|
opt.Limit = qdisc.Limit
|
||||||
opt.Loss = netem.Loss
|
opt.Loss = qdisc.Loss
|
||||||
opt.Gap = netem.Gap
|
opt.Gap = qdisc.Gap
|
||||||
opt.Duplicate = netem.Duplicate
|
opt.Duplicate = qdisc.Duplicate
|
||||||
opt.Jitter = netem.Jitter
|
opt.Jitter = qdisc.Jitter
|
||||||
options = nl.NewRtAttr(nl.TCA_OPTIONS, opt.Serialize())
|
options = nl.NewRtAttr(nl.TCA_OPTIONS, opt.Serialize())
|
||||||
// Correlation
|
// Correlation
|
||||||
corr := nl.TcNetemCorr{}
|
corr := nl.TcNetemCorr{}
|
||||||
corr.DelayCorr = netem.DelayCorr
|
corr.DelayCorr = qdisc.DelayCorr
|
||||||
corr.LossCorr = netem.LossCorr
|
corr.LossCorr = qdisc.LossCorr
|
||||||
corr.DupCorr = netem.DuplicateCorr
|
corr.DupCorr = qdisc.DuplicateCorr
|
||||||
|
|
||||||
if corr.DelayCorr > 0 || corr.LossCorr > 0 || corr.DupCorr > 0 {
|
if corr.DelayCorr > 0 || corr.LossCorr > 0 || corr.DupCorr > 0 {
|
||||||
nl.NewRtAttrChild(options, nl.TCA_NETEM_CORR, corr.Serialize())
|
nl.NewRtAttrChild(options, nl.TCA_NETEM_CORR, corr.Serialize())
|
||||||
}
|
}
|
||||||
// Corruption
|
// Corruption
|
||||||
corruption := nl.TcNetemCorrupt{}
|
corruption := nl.TcNetemCorrupt{}
|
||||||
corruption.Probability = netem.CorruptProb
|
corruption.Probability = qdisc.CorruptProb
|
||||||
corruption.Correlation = netem.CorruptCorr
|
corruption.Correlation = qdisc.CorruptCorr
|
||||||
if corruption.Probability > 0 {
|
if corruption.Probability > 0 {
|
||||||
nl.NewRtAttrChild(options, nl.TCA_NETEM_CORRUPT, corruption.Serialize())
|
nl.NewRtAttrChild(options, nl.TCA_NETEM_CORRUPT, corruption.Serialize())
|
||||||
}
|
}
|
||||||
// Reorder
|
// Reorder
|
||||||
reorder := nl.TcNetemReorder{}
|
reorder := nl.TcNetemReorder{}
|
||||||
reorder.Probability = netem.ReorderProb
|
reorder.Probability = qdisc.ReorderProb
|
||||||
reorder.Correlation = netem.ReorderCorr
|
reorder.Correlation = qdisc.ReorderCorr
|
||||||
if reorder.Probability > 0 {
|
if reorder.Probability > 0 {
|
||||||
nl.NewRtAttrChild(options, nl.TCA_NETEM_REORDER, reorder.Serialize())
|
nl.NewRtAttrChild(options, nl.TCA_NETEM_REORDER, reorder.Serialize())
|
||||||
}
|
}
|
||||||
} else if _, ok := qdisc.(*Ingress); ok {
|
case *Ingress:
|
||||||
// ingress filters must use the proper handle
|
// ingress filters must use the proper handle
|
||||||
if qdisc.Attrs().Parent != HANDLE_INGRESS {
|
if qdisc.Attrs().Parent != HANDLE_INGRESS {
|
||||||
return fmt.Errorf("Ingress filters must set Parent to HANDLE_INGRESS")
|
return fmt.Errorf("Ingress filters must set Parent to HANDLE_INGRESS")
|
||||||
|
|
62
libnetwork/vendor/github.com/vishvananda/netlink/route.go
generated
vendored
62
libnetwork/vendor/github.com/vishvananda/netlink/route.go
generated
vendored
|
@ -16,6 +16,7 @@ type Destination interface {
|
||||||
Decode([]byte) error
|
Decode([]byte) error
|
||||||
Encode() ([]byte, error)
|
Encode() ([]byte, error)
|
||||||
String() string
|
String() string
|
||||||
|
Equal(Destination) bool
|
||||||
}
|
}
|
||||||
|
|
||||||
type Encap interface {
|
type Encap interface {
|
||||||
|
@ -23,6 +24,7 @@ type Encap interface {
|
||||||
Decode([]byte) error
|
Decode([]byte) error
|
||||||
Encode() ([]byte, error)
|
Encode() ([]byte, error)
|
||||||
String() string
|
String() string
|
||||||
|
Equal(Encap) bool
|
||||||
}
|
}
|
||||||
|
|
||||||
// Route represents a netlink route.
|
// Route represents a netlink route.
|
||||||
|
@ -72,6 +74,25 @@ func (r Route) String() string {
|
||||||
return fmt.Sprintf("{%s}", strings.Join(elems, " "))
|
return fmt.Sprintf("{%s}", strings.Join(elems, " "))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (r Route) Equal(x Route) bool {
|
||||||
|
return r.LinkIndex == x.LinkIndex &&
|
||||||
|
r.ILinkIndex == x.ILinkIndex &&
|
||||||
|
r.Scope == x.Scope &&
|
||||||
|
ipNetEqual(r.Dst, x.Dst) &&
|
||||||
|
r.Src.Equal(x.Src) &&
|
||||||
|
r.Gw.Equal(x.Gw) &&
|
||||||
|
nexthopInfoSlice(r.MultiPath).Equal(x.MultiPath) &&
|
||||||
|
r.Protocol == x.Protocol &&
|
||||||
|
r.Priority == x.Priority &&
|
||||||
|
r.Table == x.Table &&
|
||||||
|
r.Type == x.Type &&
|
||||||
|
r.Tos == x.Tos &&
|
||||||
|
r.Flags == x.Flags &&
|
||||||
|
(r.MPLSDst == x.MPLSDst || (r.MPLSDst != nil && x.MPLSDst != nil && *r.MPLSDst == *x.MPLSDst)) &&
|
||||||
|
(r.NewDst == x.NewDst || (r.NewDst != nil && r.NewDst.Equal(x.NewDst))) &&
|
||||||
|
(r.Encap == x.Encap || (r.Encap != nil && r.Encap.Equal(x.Encap)))
|
||||||
|
}
|
||||||
|
|
||||||
func (r *Route) SetFlag(flag NextHopFlag) {
|
func (r *Route) SetFlag(flag NextHopFlag) {
|
||||||
r.Flags |= int(flag)
|
r.Flags |= int(flag)
|
||||||
}
|
}
|
||||||
|
@ -110,7 +131,46 @@ func (n *NexthopInfo) String() string {
|
||||||
elems = append(elems, fmt.Sprintf("Encap: %s", n.Encap))
|
elems = append(elems, fmt.Sprintf("Encap: %s", n.Encap))
|
||||||
}
|
}
|
||||||
elems = append(elems, fmt.Sprintf("Weight: %d", n.Hops+1))
|
elems = append(elems, fmt.Sprintf("Weight: %d", n.Hops+1))
|
||||||
elems = append(elems, fmt.Sprintf("Gw: %d", n.Gw))
|
elems = append(elems, fmt.Sprintf("Gw: %s", n.Gw))
|
||||||
elems = append(elems, fmt.Sprintf("Flags: %s", n.ListFlags()))
|
elems = append(elems, fmt.Sprintf("Flags: %s", n.ListFlags()))
|
||||||
return fmt.Sprintf("{%s}", strings.Join(elems, " "))
|
return fmt.Sprintf("{%s}", strings.Join(elems, " "))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (n NexthopInfo) Equal(x NexthopInfo) bool {
|
||||||
|
return n.LinkIndex == x.LinkIndex &&
|
||||||
|
n.Hops == x.Hops &&
|
||||||
|
n.Gw.Equal(x.Gw) &&
|
||||||
|
n.Flags == x.Flags &&
|
||||||
|
(n.NewDst == x.NewDst || (n.NewDst != nil && n.NewDst.Equal(x.NewDst))) &&
|
||||||
|
(n.Encap == x.Encap || (n.Encap != nil && n.Encap.Equal(x.Encap)))
|
||||||
|
}
|
||||||
|
|
||||||
|
type nexthopInfoSlice []*NexthopInfo
|
||||||
|
|
||||||
|
func (n nexthopInfoSlice) Equal(x []*NexthopInfo) bool {
|
||||||
|
if len(n) != len(x) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
for i := range n {
|
||||||
|
if n[i] == nil || x[i] == nil {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
if !n[i].Equal(*x[i]) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
// ipNetEqual returns true iff both IPNet are equal
|
||||||
|
func ipNetEqual(ipn1 *net.IPNet, ipn2 *net.IPNet) bool {
|
||||||
|
if ipn1 == ipn2 {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
if ipn1 == nil || ipn2 == nil {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
m1, _ := ipn1.Mask.Size()
|
||||||
|
m2, _ := ipn2.Mask.Size()
|
||||||
|
return m1 == m2 && ipn1.IP.Equal(ipn2.IP)
|
||||||
|
}
|
||||||
|
|
101
libnetwork/vendor/github.com/vishvananda/netlink/route_linux.go
generated
vendored
101
libnetwork/vendor/github.com/vishvananda/netlink/route_linux.go
generated
vendored
|
@ -86,6 +86,34 @@ func (d *MPLSDestination) String() string {
|
||||||
return strings.Join(s, "/")
|
return strings.Join(s, "/")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (d *MPLSDestination) Equal(x Destination) bool {
|
||||||
|
o, ok := x.(*MPLSDestination)
|
||||||
|
if !ok {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
if d == nil && o == nil {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
if d == nil || o == nil {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
if d.Labels == nil && o.Labels == nil {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
if d.Labels == nil || o.Labels == nil {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
if len(d.Labels) != len(o.Labels) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
for i := range d.Labels {
|
||||||
|
if d.Labels[i] != o.Labels[i] {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
type MPLSEncap struct {
|
type MPLSEncap struct {
|
||||||
Labels []int
|
Labels []int
|
||||||
}
|
}
|
||||||
|
@ -129,6 +157,34 @@ func (e *MPLSEncap) String() string {
|
||||||
return strings.Join(s, "/")
|
return strings.Join(s, "/")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (e *MPLSEncap) Equal(x Encap) bool {
|
||||||
|
o, ok := x.(*MPLSEncap)
|
||||||
|
if !ok {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
if e == nil && o == nil {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
if e == nil || o == nil {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
if e.Labels == nil && o.Labels == nil {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
if e.Labels == nil || o.Labels == nil {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
if len(e.Labels) != len(o.Labels) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
for i := range e.Labels {
|
||||||
|
if e.Labels[i] != o.Labels[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 {
|
||||||
|
@ -421,19 +477,8 @@ func (h *Handle) RouteListFiltered(family int, filter *Route, filterMask uint64)
|
||||||
continue
|
continue
|
||||||
case filterMask&RT_FILTER_DST != 0:
|
case filterMask&RT_FILTER_DST != 0:
|
||||||
if filter.MPLSDst == nil || route.MPLSDst == nil || (*filter.MPLSDst) != (*route.MPLSDst) {
|
if filter.MPLSDst == nil || route.MPLSDst == nil || (*filter.MPLSDst) != (*route.MPLSDst) {
|
||||||
if filter.Dst == nil {
|
if !ipNetEqual(route.Dst, filter.Dst) {
|
||||||
if route.Dst != nil {
|
continue
|
||||||
continue
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if route.Dst == nil {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
aMaskLen, aMaskBits := route.Dst.Mask.Size()
|
|
||||||
bMaskLen, bMaskBits := filter.Dst.Mask.Size()
|
|
||||||
if !(route.Dst.IP.Equal(filter.Dst.IP) && aMaskLen == bMaskLen && aMaskBits == bMaskBits) {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -633,16 +678,34 @@ func (h *Handle) RouteGet(destination net.IP) ([]Route, error) {
|
||||||
// RouteSubscribe takes a chan down which notifications will be sent
|
// RouteSubscribe takes a chan down which notifications will be sent
|
||||||
// when routes are added or deleted. Close the 'done' chan to stop subscription.
|
// when routes are added or deleted. Close the 'done' chan to stop subscription.
|
||||||
func RouteSubscribe(ch chan<- RouteUpdate, done <-chan struct{}) error {
|
func RouteSubscribe(ch chan<- RouteUpdate, done <-chan struct{}) error {
|
||||||
return routeSubscribeAt(netns.None(), netns.None(), ch, done)
|
return routeSubscribeAt(netns.None(), netns.None(), ch, done, nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
// RouteSubscribeAt works like RouteSubscribe plus it allows the caller
|
// RouteSubscribeAt works like RouteSubscribe plus it allows the caller
|
||||||
// to choose the network namespace in which to subscribe (ns).
|
// to choose the network namespace in which to subscribe (ns).
|
||||||
func RouteSubscribeAt(ns netns.NsHandle, ch chan<- RouteUpdate, done <-chan struct{}) error {
|
func RouteSubscribeAt(ns netns.NsHandle, ch chan<- RouteUpdate, done <-chan struct{}) error {
|
||||||
return routeSubscribeAt(ns, netns.None(), ch, done)
|
return routeSubscribeAt(ns, netns.None(), ch, done, nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
func routeSubscribeAt(newNs, curNs netns.NsHandle, ch chan<- RouteUpdate, done <-chan struct{}) error {
|
// RouteSubscribeOptions contains a set of options to use with
|
||||||
|
// RouteSubscribeWithOptions.
|
||||||
|
type RouteSubscribeOptions struct {
|
||||||
|
Namespace *netns.NsHandle
|
||||||
|
ErrorCallback func(error)
|
||||||
|
}
|
||||||
|
|
||||||
|
// RouteSubscribeWithOptions work like RouteSubscribe but enable to
|
||||||
|
// provide additional options to modify the behavior. Currently, the
|
||||||
|
// namespace can be provided as well as an error callback.
|
||||||
|
func RouteSubscribeWithOptions(ch chan<- RouteUpdate, done <-chan struct{}, options RouteSubscribeOptions) error {
|
||||||
|
if options.Namespace == nil {
|
||||||
|
none := netns.None()
|
||||||
|
options.Namespace = &none
|
||||||
|
}
|
||||||
|
return routeSubscribeAt(*options.Namespace, netns.None(), ch, done, options.ErrorCallback)
|
||||||
|
}
|
||||||
|
|
||||||
|
func routeSubscribeAt(newNs, curNs netns.NsHandle, ch chan<- RouteUpdate, done <-chan struct{}, cberr func(error)) error {
|
||||||
s, err := nl.SubscribeAt(newNs, curNs, syscall.NETLINK_ROUTE, syscall.RTNLGRP_IPV4_ROUTE, syscall.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
|
||||||
|
@ -658,11 +721,17 @@ func routeSubscribeAt(newNs, curNs netns.NsHandle, ch chan<- RouteUpdate, done <
|
||||||
for {
|
for {
|
||||||
msgs, err := s.Receive()
|
msgs, err := s.Receive()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
if cberr != nil {
|
||||||
|
cberr(err)
|
||||||
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
for _, m := range msgs {
|
for _, m := range msgs {
|
||||||
route, err := deserializeRoute(m.Data)
|
route, err := deserializeRoute(m.Data)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
if cberr != nil {
|
||||||
|
cberr(err)
|
||||||
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
ch <- RouteUpdate{Type: m.Header.Type, Route: route}
|
ch <- RouteUpdate{Type: m.Header.Type, Route: route}
|
||||||
|
|
1
libnetwork/vendor/github.com/vishvananda/netlink/rule.go
generated
vendored
1
libnetwork/vendor/github.com/vishvananda/netlink/rule.go
generated
vendored
|
@ -8,6 +8,7 @@ import (
|
||||||
// Rule represents a netlink rule.
|
// Rule represents a netlink rule.
|
||||||
type Rule struct {
|
type Rule struct {
|
||||||
Priority int
|
Priority int
|
||||||
|
Family int
|
||||||
Table int
|
Table int
|
||||||
Mark int
|
Mark int
|
||||||
Mask int
|
Mask int
|
||||||
|
|
3
libnetwork/vendor/github.com/vishvananda/netlink/rule_linux.go
generated
vendored
3
libnetwork/vendor/github.com/vishvananda/netlink/rule_linux.go
generated
vendored
|
@ -37,6 +37,9 @@ func (h *Handle) RuleDel(rule *Rule) error {
|
||||||
func ruleHandle(rule *Rule, req *nl.NetlinkRequest) error {
|
func ruleHandle(rule *Rule, req *nl.NetlinkRequest) error {
|
||||||
msg := nl.NewRtMsg()
|
msg := nl.NewRtMsg()
|
||||||
msg.Family = syscall.AF_INET
|
msg.Family = syscall.AF_INET
|
||||||
|
if rule.Family != 0 {
|
||||||
|
msg.Family = uint8(rule.Family)
|
||||||
|
}
|
||||||
var dstFamily uint8
|
var dstFamily uint8
|
||||||
|
|
||||||
var rtAttrs []*nl.RtAttr
|
var rtAttrs []*nl.RtAttr
|
||||||
|
|
Loading…
Add table
Reference in a new issue