Update netlink library.
Signed-off-by: Dimitri John Ledkov <dimitri.j.ledkov@intel.com>
This commit is contained in:
parent
2509014be8
commit
27908bfeb4
30 changed files with 1989 additions and 1847 deletions
4
libnetwork/Godeps/Godeps.json
generated
4
libnetwork/Godeps/Godeps.json
generated
|
@ -216,11 +216,11 @@
|
|||
},
|
||||
{
|
||||
"ImportPath": "github.com/vishvananda/netlink",
|
||||
"Rev": "4b5dce31de6d42af5bb9811c6d265472199e0fec"
|
||||
"Rev": "8e810149a2e531fed9b837c0c7d8a8922d2bedf7"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/vishvananda/netns",
|
||||
"Rev": "493029407eeb434d0c2d44e02ea072ff2488d322"
|
||||
"Rev": "604eaf189ee867d8c147fafc28def2394e878d25"
|
||||
},
|
||||
{
|
||||
"ImportPath": "golang.org/x/net/context",
|
||||
|
|
45
libnetwork/Godeps/_workspace/src/github.com/vishvananda/netlink/addr_test.go
generated
vendored
45
libnetwork/Godeps/_workspace/src/github.com/vishvananda/netlink/addr_test.go
generated
vendored
|
@ -1,45 +0,0 @@
|
|||
package netlink
|
||||
|
||||
import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestAddrAddDel(t *testing.T) {
|
||||
tearDown := setUpNetlinkTest(t)
|
||||
defer tearDown()
|
||||
|
||||
link, err := LinkByName("lo")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
addr, err := ParseAddr("127.1.1.1/24 local")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if err = AddrAdd(link, addr); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
addrs, err := AddrList(link, FAMILY_ALL)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if len(addrs) != 1 || !addr.Equal(addrs[0]) || addrs[0].Label != addr.Label {
|
||||
t.Fatal("Address not added properly")
|
||||
}
|
||||
|
||||
if err = AddrDel(link, addr); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
addrs, err = AddrList(link, FAMILY_ALL)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if len(addrs) != 0 {
|
||||
t.Fatal("Address not removed properly")
|
||||
}
|
||||
}
|
110
libnetwork/Godeps/_workspace/src/github.com/vishvananda/netlink/class.go
generated
vendored
Normal file
110
libnetwork/Godeps/_workspace/src/github.com/vishvananda/netlink/class.go
generated
vendored
Normal file
|
@ -0,0 +1,110 @@
|
|||
package netlink
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
)
|
||||
|
||||
type Class interface {
|
||||
Attrs() *ClassAttrs
|
||||
Type() string
|
||||
}
|
||||
|
||||
// Class represents a netlink class. A filter is associated with a link,
|
||||
// has a handle and a parent. The root filter of a device should have a
|
||||
// parent == HANDLE_ROOT.
|
||||
type ClassAttrs struct {
|
||||
LinkIndex int
|
||||
Handle uint32
|
||||
Parent uint32
|
||||
Leaf uint32
|
||||
}
|
||||
|
||||
func (q ClassAttrs) String() string {
|
||||
return fmt.Sprintf("{LinkIndex: %d, Handle: %s, Parent: %s, Leaf: %s}", q.LinkIndex, HandleStr(q.Handle), HandleStr(q.Parent), q.Leaf)
|
||||
}
|
||||
|
||||
type HtbClassAttrs struct {
|
||||
// TODO handle all attributes
|
||||
Rate uint64
|
||||
Ceil uint64
|
||||
Buffer uint32
|
||||
Cbuffer uint32
|
||||
Quantum uint32
|
||||
Level uint32
|
||||
Prio uint32
|
||||
}
|
||||
|
||||
func (q HtbClassAttrs) String() string {
|
||||
return fmt.Sprintf("{Rate: %d, Ceil: %d, Buffer: %d, Cbuffer: %d}", q.Rate, q.Ceil, q.Buffer, q.Cbuffer)
|
||||
}
|
||||
|
||||
// Htb class
|
||||
type HtbClass struct {
|
||||
ClassAttrs
|
||||
Rate uint64
|
||||
Ceil uint64
|
||||
Buffer uint32
|
||||
Cbuffer uint32
|
||||
Quantum uint32
|
||||
Level uint32
|
||||
Prio uint32
|
||||
}
|
||||
|
||||
func NewHtbClass(attrs ClassAttrs, cattrs HtbClassAttrs) *HtbClass {
|
||||
mtu := 1600
|
||||
rate := cattrs.Rate / 8
|
||||
ceil := cattrs.Ceil / 8
|
||||
buffer := cattrs.Buffer
|
||||
cbuffer := cattrs.Cbuffer
|
||||
if ceil == 0 {
|
||||
ceil = rate
|
||||
}
|
||||
|
||||
if buffer == 0 {
|
||||
buffer = uint32(float64(rate)/Hz() + float64(mtu))
|
||||
}
|
||||
buffer = uint32(Xmittime(rate, buffer))
|
||||
|
||||
if cbuffer == 0 {
|
||||
cbuffer = uint32(float64(ceil)/Hz() + float64(mtu))
|
||||
}
|
||||
cbuffer = uint32(Xmittime(ceil, cbuffer))
|
||||
|
||||
return &HtbClass{
|
||||
ClassAttrs: attrs,
|
||||
Rate: rate,
|
||||
Ceil: ceil,
|
||||
Buffer: buffer,
|
||||
Cbuffer: cbuffer,
|
||||
Quantum: 10,
|
||||
Level: 0,
|
||||
Prio: 0,
|
||||
}
|
||||
}
|
||||
|
||||
func (q HtbClass) String() string {
|
||||
return fmt.Sprintf("{Rate: %d, Ceil: %d, Buffer: %d, Cbuffer: %d}", q.Rate, q.Ceil, q.Buffer, q.Cbuffer)
|
||||
}
|
||||
|
||||
func (class *HtbClass) Attrs() *ClassAttrs {
|
||||
return &class.ClassAttrs
|
||||
}
|
||||
|
||||
func (class *HtbClass) Type() string {
|
||||
return "htb"
|
||||
}
|
||||
|
||||
// GenericClass classes represent types that are not currently understood
|
||||
// by this netlink library.
|
||||
type GenericClass struct {
|
||||
ClassAttrs
|
||||
ClassType string
|
||||
}
|
||||
|
||||
func (class *GenericClass) Attrs() *ClassAttrs {
|
||||
return &class.ClassAttrs
|
||||
}
|
||||
|
||||
func (class *GenericClass) Type() string {
|
||||
return class.ClassType
|
||||
}
|
144
libnetwork/Godeps/_workspace/src/github.com/vishvananda/netlink/class_linux.go
generated
vendored
Normal file
144
libnetwork/Godeps/_workspace/src/github.com/vishvananda/netlink/class_linux.go
generated
vendored
Normal file
|
@ -0,0 +1,144 @@
|
|||
package netlink
|
||||
|
||||
import (
|
||||
"syscall"
|
||||
|
||||
"github.com/vishvananda/netlink/nl"
|
||||
)
|
||||
|
||||
// ClassDel will delete a class from the system.
|
||||
// Equivalent to: `tc class del $class`
|
||||
func ClassDel(class Class) error {
|
||||
req := nl.NewNetlinkRequest(syscall.RTM_DELTCLASS, syscall.NLM_F_ACK)
|
||||
base := class.Attrs()
|
||||
msg := &nl.TcMsg{
|
||||
Family: nl.FAMILY_ALL,
|
||||
Ifindex: int32(base.LinkIndex),
|
||||
Handle: base.Handle,
|
||||
Parent: base.Parent,
|
||||
}
|
||||
req.AddData(msg)
|
||||
|
||||
_, err := req.Execute(syscall.NETLINK_ROUTE, 0)
|
||||
return err
|
||||
}
|
||||
|
||||
// ClassAdd will add a class to the system.
|
||||
// Equivalent to: `tc class add $class`
|
||||
func ClassAdd(class Class) error {
|
||||
req := nl.NewNetlinkRequest(syscall.RTM_NEWTCLASS, syscall.NLM_F_CREATE|syscall.NLM_F_EXCL|syscall.NLM_F_ACK)
|
||||
base := class.Attrs()
|
||||
msg := &nl.TcMsg{
|
||||
Family: nl.FAMILY_ALL,
|
||||
Ifindex: int32(base.LinkIndex),
|
||||
Handle: base.Handle,
|
||||
Parent: base.Parent,
|
||||
}
|
||||
req.AddData(msg)
|
||||
req.AddData(nl.NewRtAttr(nl.TCA_KIND, nl.ZeroTerminated(class.Type())))
|
||||
|
||||
options := nl.NewRtAttr(nl.TCA_OPTIONS, nil)
|
||||
if htb, ok := class.(*HtbClass); ok {
|
||||
opt := nl.TcHtbCopt{}
|
||||
opt.Rate.Rate = uint32(htb.Rate)
|
||||
opt.Ceil.Rate = uint32(htb.Ceil)
|
||||
opt.Buffer = htb.Buffer
|
||||
opt.Cbuffer = htb.Cbuffer
|
||||
opt.Quantum = htb.Quantum
|
||||
opt.Level = htb.Level
|
||||
opt.Prio = htb.Prio
|
||||
// TODO: Handle Debug properly. For now default to 0
|
||||
nl.NewRtAttrChild(options, nl.TCA_HTB_PARMS, opt.Serialize())
|
||||
}
|
||||
req.AddData(options)
|
||||
_, err := req.Execute(syscall.NETLINK_ROUTE, 0)
|
||||
return err
|
||||
}
|
||||
|
||||
// ClassList gets a list of classes in the system.
|
||||
// Equivalent to: `tc class show`.
|
||||
// Generally retunrs nothing if link and parent are not specified.
|
||||
func ClassList(link Link, parent uint32) ([]Class, error) {
|
||||
req := nl.NewNetlinkRequest(syscall.RTM_GETTCLASS, syscall.NLM_F_DUMP)
|
||||
msg := &nl.TcMsg{
|
||||
Family: nl.FAMILY_ALL,
|
||||
Parent: parent,
|
||||
}
|
||||
if link != nil {
|
||||
base := link.Attrs()
|
||||
ensureIndex(base)
|
||||
msg.Ifindex = int32(base.Index)
|
||||
}
|
||||
req.AddData(msg)
|
||||
|
||||
msgs, err := req.Execute(syscall.NETLINK_ROUTE, syscall.RTM_NEWTCLASS)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var res []Class
|
||||
for _, m := range msgs {
|
||||
msg := nl.DeserializeTcMsg(m)
|
||||
|
||||
attrs, err := nl.ParseRouteAttr(m[msg.Len():])
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
base := ClassAttrs{
|
||||
LinkIndex: int(msg.Ifindex),
|
||||
Handle: msg.Handle,
|
||||
Parent: msg.Parent,
|
||||
}
|
||||
|
||||
var class Class
|
||||
classType := ""
|
||||
for _, attr := range attrs {
|
||||
switch attr.Attr.Type {
|
||||
case nl.TCA_KIND:
|
||||
classType = string(attr.Value[:len(attr.Value)-1])
|
||||
switch classType {
|
||||
case "htb":
|
||||
class = &HtbClass{}
|
||||
default:
|
||||
class = &GenericClass{ClassType: classType}
|
||||
}
|
||||
case nl.TCA_OPTIONS:
|
||||
switch classType {
|
||||
case "htb":
|
||||
data, err := nl.ParseRouteAttr(attr.Value)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
_, err = parseHtbClassData(class, data)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
*class.Attrs() = base
|
||||
res = append(res, class)
|
||||
}
|
||||
|
||||
return res, nil
|
||||
}
|
||||
|
||||
func parseHtbClassData(class Class, data []syscall.NetlinkRouteAttr) (bool, error) {
|
||||
htb := class.(*HtbClass)
|
||||
detailed := false
|
||||
for _, datum := range data {
|
||||
switch datum.Attr.Type {
|
||||
case nl.TCA_HTB_PARMS:
|
||||
opt := nl.DeserializeTcHtbCopt(datum.Value)
|
||||
htb.Rate = uint64(opt.Rate.Rate)
|
||||
htb.Ceil = uint64(opt.Ceil.Rate)
|
||||
htb.Buffer = opt.Buffer
|
||||
htb.Cbuffer = opt.Cbuffer
|
||||
htb.Quantum = opt.Quantum
|
||||
htb.Level = opt.Level
|
||||
htb.Prio = opt.Prio
|
||||
}
|
||||
}
|
||||
return detailed, nil
|
||||
}
|
140
libnetwork/Godeps/_workspace/src/github.com/vishvananda/netlink/filter.go
generated
vendored
Normal file
140
libnetwork/Godeps/_workspace/src/github.com/vishvananda/netlink/filter.go
generated
vendored
Normal file
|
@ -0,0 +1,140 @@
|
|||
package netlink
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"github.com/vishvananda/netlink/nl"
|
||||
)
|
||||
|
||||
type Filter interface {
|
||||
Attrs() *FilterAttrs
|
||||
Type() string
|
||||
}
|
||||
|
||||
// Filter represents a netlink filter. A filter is associated with a link,
|
||||
// has a handle and a parent. The root filter of a device should have a
|
||||
// parent == HANDLE_ROOT.
|
||||
type FilterAttrs struct {
|
||||
LinkIndex int
|
||||
Handle uint32
|
||||
Parent uint32
|
||||
Priority uint16 // lower is higher priority
|
||||
Protocol uint16 // syscall.ETH_P_*
|
||||
}
|
||||
|
||||
func (q FilterAttrs) String() string {
|
||||
return fmt.Sprintf("{LinkIndex: %d, Handle: %s, Parent: %s, Priority: %d, Protocol: %d}", q.LinkIndex, HandleStr(q.Handle), HandleStr(q.Parent), q.Priority, q.Protocol)
|
||||
}
|
||||
|
||||
// U32 filters on many packet related properties
|
||||
type U32 struct {
|
||||
FilterAttrs
|
||||
// Currently only supports redirecting to another interface
|
||||
RedirIndex int
|
||||
}
|
||||
|
||||
func (filter *U32) Attrs() *FilterAttrs {
|
||||
return &filter.FilterAttrs
|
||||
}
|
||||
|
||||
func (filter *U32) Type() string {
|
||||
return "u32"
|
||||
}
|
||||
|
||||
type FilterFwAttrs struct {
|
||||
ClassId uint32
|
||||
InDev string
|
||||
Mask uint32
|
||||
Index uint32
|
||||
Buffer uint32
|
||||
Mtu uint32
|
||||
Mpu uint16
|
||||
Rate uint32
|
||||
AvRate uint32
|
||||
PeakRate uint32
|
||||
Action int
|
||||
Overhead uint16
|
||||
LinkLayer int
|
||||
}
|
||||
|
||||
// FwFilter filters on firewall marks
|
||||
type Fw struct {
|
||||
FilterAttrs
|
||||
ClassId uint32
|
||||
Police nl.TcPolice
|
||||
InDev string
|
||||
// TODO Action
|
||||
Mask uint32
|
||||
AvRate uint32
|
||||
Rtab [256]uint32
|
||||
Ptab [256]uint32
|
||||
}
|
||||
|
||||
func NewFw(attrs FilterAttrs, fattrs FilterFwAttrs) (*Fw, error) {
|
||||
var rtab [256]uint32
|
||||
var ptab [256]uint32
|
||||
rcell_log := -1
|
||||
pcell_log := -1
|
||||
avrate := fattrs.AvRate / 8
|
||||
police := nl.TcPolice{}
|
||||
police.Rate.Rate = fattrs.Rate / 8
|
||||
police.PeakRate.Rate = fattrs.PeakRate / 8
|
||||
buffer := fattrs.Buffer
|
||||
linklayer := nl.LINKLAYER_ETHERNET
|
||||
|
||||
if fattrs.LinkLayer != nl.LINKLAYER_UNSPEC {
|
||||
linklayer = fattrs.LinkLayer
|
||||
}
|
||||
|
||||
police.Action = int32(fattrs.Action)
|
||||
if police.Rate.Rate != 0 {
|
||||
police.Rate.Mpu = fattrs.Mpu
|
||||
police.Rate.Overhead = fattrs.Overhead
|
||||
if CalcRtable(&police.Rate, rtab, rcell_log, fattrs.Mtu, linklayer) < 0 {
|
||||
return nil, errors.New("TBF: failed to calculate rate table.")
|
||||
}
|
||||
police.Burst = uint32(Xmittime(uint64(police.Rate.Rate), uint32(buffer)))
|
||||
}
|
||||
police.Mtu = fattrs.Mtu
|
||||
if police.PeakRate.Rate != 0 {
|
||||
police.PeakRate.Mpu = fattrs.Mpu
|
||||
police.PeakRate.Overhead = fattrs.Overhead
|
||||
if CalcRtable(&police.PeakRate, ptab, pcell_log, fattrs.Mtu, linklayer) < 0 {
|
||||
return nil, errors.New("POLICE: failed to calculate peak rate table.")
|
||||
}
|
||||
}
|
||||
|
||||
return &Fw{
|
||||
FilterAttrs: attrs,
|
||||
ClassId: fattrs.ClassId,
|
||||
InDev: fattrs.InDev,
|
||||
Mask: fattrs.Mask,
|
||||
Police: police,
|
||||
AvRate: avrate,
|
||||
Rtab: rtab,
|
||||
Ptab: ptab,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (filter *Fw) Attrs() *FilterAttrs {
|
||||
return &filter.FilterAttrs
|
||||
}
|
||||
|
||||
func (filter *Fw) Type() string {
|
||||
return "fw"
|
||||
}
|
||||
|
||||
// GenericFilter filters represent types that are not currently understood
|
||||
// by this netlink library.
|
||||
type GenericFilter struct {
|
||||
FilterAttrs
|
||||
FilterType string
|
||||
}
|
||||
|
||||
func (filter *GenericFilter) Attrs() *FilterAttrs {
|
||||
return &filter.FilterAttrs
|
||||
}
|
||||
|
||||
func (filter *GenericFilter) Type() string {
|
||||
return filter.FilterType
|
||||
}
|
322
libnetwork/Godeps/_workspace/src/github.com/vishvananda/netlink/filter_linux.go
generated
vendored
Normal file
322
libnetwork/Godeps/_workspace/src/github.com/vishvananda/netlink/filter_linux.go
generated
vendored
Normal file
|
@ -0,0 +1,322 @@
|
|||
package netlink
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/binary"
|
||||
"fmt"
|
||||
"syscall"
|
||||
|
||||
"github.com/vishvananda/netlink/nl"
|
||||
)
|
||||
|
||||
// FilterDel will delete a filter from the system.
|
||||
// Equivalent to: `tc filter del $filter`
|
||||
func FilterDel(filter Filter) error {
|
||||
req := nl.NewNetlinkRequest(syscall.RTM_DELTFILTER, syscall.NLM_F_ACK)
|
||||
base := filter.Attrs()
|
||||
msg := &nl.TcMsg{
|
||||
Family: nl.FAMILY_ALL,
|
||||
Ifindex: int32(base.LinkIndex),
|
||||
Handle: base.Handle,
|
||||
Parent: base.Parent,
|
||||
Info: MakeHandle(base.Priority, nl.Swap16(base.Protocol)),
|
||||
}
|
||||
req.AddData(msg)
|
||||
|
||||
_, err := req.Execute(syscall.NETLINK_ROUTE, 0)
|
||||
return err
|
||||
}
|
||||
|
||||
// FilterAdd will add a filter to the system.
|
||||
// Equivalent to: `tc filter add $filter`
|
||||
func FilterAdd(filter Filter) error {
|
||||
native = nl.NativeEndian()
|
||||
req := nl.NewNetlinkRequest(syscall.RTM_NEWTFILTER, syscall.NLM_F_CREATE|syscall.NLM_F_EXCL|syscall.NLM_F_ACK)
|
||||
base := filter.Attrs()
|
||||
msg := &nl.TcMsg{
|
||||
Family: nl.FAMILY_ALL,
|
||||
Ifindex: int32(base.LinkIndex),
|
||||
Handle: base.Handle,
|
||||
Parent: base.Parent,
|
||||
Info: MakeHandle(base.Priority, nl.Swap16(base.Protocol)),
|
||||
}
|
||||
req.AddData(msg)
|
||||
req.AddData(nl.NewRtAttr(nl.TCA_KIND, nl.ZeroTerminated(filter.Type())))
|
||||
|
||||
options := nl.NewRtAttr(nl.TCA_OPTIONS, nil)
|
||||
if u32, ok := filter.(*U32); ok {
|
||||
// match all
|
||||
sel := nl.TcU32Sel{
|
||||
Nkeys: 1,
|
||||
Flags: nl.TC_U32_TERMINAL,
|
||||
}
|
||||
sel.Keys = append(sel.Keys, nl.TcU32Key{})
|
||||
nl.NewRtAttrChild(options, nl.TCA_U32_SEL, sel.Serialize())
|
||||
actions := nl.NewRtAttrChild(options, nl.TCA_U32_ACT, nil)
|
||||
table := nl.NewRtAttrChild(actions, nl.TCA_ACT_TAB, nil)
|
||||
nl.NewRtAttrChild(table, nl.TCA_KIND, nl.ZeroTerminated("mirred"))
|
||||
// redirect to other interface
|
||||
mir := nl.TcMirred{
|
||||
Action: nl.TC_ACT_STOLEN,
|
||||
Eaction: nl.TCA_EGRESS_REDIR,
|
||||
Ifindex: uint32(u32.RedirIndex),
|
||||
}
|
||||
aopts := nl.NewRtAttrChild(table, nl.TCA_OPTIONS, nil)
|
||||
nl.NewRtAttrChild(aopts, nl.TCA_MIRRED_PARMS, mir.Serialize())
|
||||
} else if fw, ok := filter.(*Fw); ok {
|
||||
if fw.Mask != 0 {
|
||||
b := make([]byte, 4)
|
||||
native.PutUint32(b, fw.Mask)
|
||||
nl.NewRtAttrChild(options, nl.TCA_FW_MASK, b)
|
||||
}
|
||||
if fw.InDev != "" {
|
||||
nl.NewRtAttrChild(options, nl.TCA_FW_INDEV, nl.ZeroTerminated(fw.InDev))
|
||||
}
|
||||
if (fw.Police != nl.TcPolice{}) {
|
||||
|
||||
police := nl.NewRtAttrChild(options, nl.TCA_FW_POLICE, nil)
|
||||
nl.NewRtAttrChild(police, nl.TCA_POLICE_TBF, fw.Police.Serialize())
|
||||
if (fw.Police.Rate != nl.TcRateSpec{}) {
|
||||
payload := SerializeRtab(fw.Rtab)
|
||||
nl.NewRtAttrChild(police, nl.TCA_POLICE_RATE, payload)
|
||||
}
|
||||
if (fw.Police.PeakRate != nl.TcRateSpec{}) {
|
||||
payload := SerializeRtab(fw.Ptab)
|
||||
nl.NewRtAttrChild(police, nl.TCA_POLICE_PEAKRATE, payload)
|
||||
}
|
||||
}
|
||||
if fw.ClassId != 0 {
|
||||
b := make([]byte, 4)
|
||||
native.PutUint32(b, fw.ClassId)
|
||||
nl.NewRtAttrChild(options, nl.TCA_FW_CLASSID, b)
|
||||
}
|
||||
}
|
||||
|
||||
req.AddData(options)
|
||||
_, err := req.Execute(syscall.NETLINK_ROUTE, 0)
|
||||
return err
|
||||
}
|
||||
|
||||
// FilterList gets a list of filters in the system.
|
||||
// Equivalent to: `tc filter show`.
|
||||
// Generally retunrs nothing if link and parent are not specified.
|
||||
func FilterList(link Link, parent uint32) ([]Filter, error) {
|
||||
req := nl.NewNetlinkRequest(syscall.RTM_GETTFILTER, syscall.NLM_F_DUMP)
|
||||
msg := &nl.TcMsg{
|
||||
Family: nl.FAMILY_ALL,
|
||||
Parent: parent,
|
||||
}
|
||||
if link != nil {
|
||||
base := link.Attrs()
|
||||
ensureIndex(base)
|
||||
msg.Ifindex = int32(base.Index)
|
||||
}
|
||||
req.AddData(msg)
|
||||
|
||||
msgs, err := req.Execute(syscall.NETLINK_ROUTE, syscall.RTM_NEWTFILTER)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var res []Filter
|
||||
for _, m := range msgs {
|
||||
msg := nl.DeserializeTcMsg(m)
|
||||
|
||||
attrs, err := nl.ParseRouteAttr(m[msg.Len():])
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
base := FilterAttrs{
|
||||
LinkIndex: int(msg.Ifindex),
|
||||
Handle: msg.Handle,
|
||||
Parent: msg.Parent,
|
||||
}
|
||||
base.Priority, base.Protocol = MajorMinor(msg.Info)
|
||||
base.Protocol = nl.Swap16(base.Protocol)
|
||||
|
||||
var filter Filter
|
||||
filterType := ""
|
||||
detailed := false
|
||||
for _, attr := range attrs {
|
||||
switch attr.Attr.Type {
|
||||
case nl.TCA_KIND:
|
||||
filterType = string(attr.Value[:len(attr.Value)-1])
|
||||
switch filterType {
|
||||
case "u32":
|
||||
filter = &U32{}
|
||||
case "fw":
|
||||
filter = &Fw{}
|
||||
default:
|
||||
filter = &GenericFilter{FilterType: filterType}
|
||||
}
|
||||
case nl.TCA_OPTIONS:
|
||||
switch filterType {
|
||||
case "u32":
|
||||
data, err := nl.ParseRouteAttr(attr.Value)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
detailed, err = parseU32Data(filter, data)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
case "fw":
|
||||
data, err := nl.ParseRouteAttr(attr.Value)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
detailed, err = parseFwData(filter, data)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// only return the detailed version of the filter
|
||||
if detailed {
|
||||
*filter.Attrs() = base
|
||||
res = append(res, filter)
|
||||
}
|
||||
}
|
||||
|
||||
return res, nil
|
||||
}
|
||||
|
||||
func parseU32Data(filter Filter, data []syscall.NetlinkRouteAttr) (bool, error) {
|
||||
native = nl.NativeEndian()
|
||||
u32 := filter.(*U32)
|
||||
detailed := false
|
||||
for _, datum := range data {
|
||||
switch datum.Attr.Type {
|
||||
case nl.TCA_U32_SEL:
|
||||
detailed = true
|
||||
sel := nl.DeserializeTcU32Sel(datum.Value)
|
||||
// only parse if we have a very basic redirect
|
||||
if sel.Flags&nl.TC_U32_TERMINAL == 0 || sel.Nkeys != 1 {
|
||||
return detailed, nil
|
||||
}
|
||||
case nl.TCA_U32_ACT:
|
||||
table, err := nl.ParseRouteAttr(datum.Value)
|
||||
if err != nil {
|
||||
return detailed, err
|
||||
}
|
||||
if len(table) != 1 || table[0].Attr.Type != nl.TCA_ACT_TAB {
|
||||
return detailed, fmt.Errorf("Action table not formed properly")
|
||||
}
|
||||
aattrs, err := nl.ParseRouteAttr(table[0].Value)
|
||||
for _, aattr := range aattrs {
|
||||
switch aattr.Attr.Type {
|
||||
case nl.TCA_KIND:
|
||||
actionType := string(aattr.Value[:len(aattr.Value)-1])
|
||||
// only parse if the action is mirred
|
||||
if actionType != "mirred" {
|
||||
return detailed, nil
|
||||
}
|
||||
case nl.TCA_OPTIONS:
|
||||
adata, err := nl.ParseRouteAttr(aattr.Value)
|
||||
if err != nil {
|
||||
return detailed, err
|
||||
}
|
||||
for _, adatum := range adata {
|
||||
switch adatum.Attr.Type {
|
||||
case nl.TCA_MIRRED_PARMS:
|
||||
mir := nl.DeserializeTcMirred(adatum.Value)
|
||||
u32.RedirIndex = int(mir.Ifindex)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return detailed, nil
|
||||
}
|
||||
|
||||
func parseFwData(filter Filter, data []syscall.NetlinkRouteAttr) (bool, error) {
|
||||
native = nl.NativeEndian()
|
||||
fw := filter.(*Fw)
|
||||
detailed := true
|
||||
for _, datum := range data {
|
||||
switch datum.Attr.Type {
|
||||
case nl.TCA_FW_MASK:
|
||||
fw.Mask = native.Uint32(datum.Value[0:4])
|
||||
case nl.TCA_FW_CLASSID:
|
||||
fw.ClassId = native.Uint32(datum.Value[0:4])
|
||||
case nl.TCA_FW_INDEV:
|
||||
fw.InDev = string(datum.Value[:len(datum.Value)-1])
|
||||
case nl.TCA_FW_POLICE:
|
||||
adata, _ := nl.ParseRouteAttr(datum.Value)
|
||||
for _, aattr := range adata {
|
||||
switch aattr.Attr.Type {
|
||||
case nl.TCA_POLICE_TBF:
|
||||
fw.Police = *nl.DeserializeTcPolice(aattr.Value)
|
||||
case nl.TCA_POLICE_RATE:
|
||||
fw.Rtab = DeserializeRtab(aattr.Value)
|
||||
case nl.TCA_POLICE_PEAKRATE:
|
||||
fw.Ptab = DeserializeRtab(aattr.Value)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return detailed, nil
|
||||
}
|
||||
|
||||
func AlignToAtm(size uint) uint {
|
||||
var linksize, cells int
|
||||
cells = int(size / nl.ATM_CELL_PAYLOAD)
|
||||
if (size % nl.ATM_CELL_PAYLOAD) > 0 {
|
||||
cells++
|
||||
}
|
||||
linksize = cells * nl.ATM_CELL_SIZE
|
||||
return uint(linksize)
|
||||
}
|
||||
|
||||
func AdjustSize(sz uint, mpu uint, linklayer int) uint {
|
||||
if sz < mpu {
|
||||
sz = mpu
|
||||
}
|
||||
switch linklayer {
|
||||
case nl.LINKLAYER_ATM:
|
||||
return AlignToAtm(sz)
|
||||
default:
|
||||
return sz
|
||||
}
|
||||
}
|
||||
|
||||
func CalcRtable(rate *nl.TcRateSpec, rtab [256]uint32, cell_log int, mtu uint32, linklayer int) int {
|
||||
bps := rate.Rate
|
||||
mpu := rate.Mpu
|
||||
var sz uint
|
||||
if mtu == 0 {
|
||||
mtu = 2047
|
||||
}
|
||||
if cell_log < 0 {
|
||||
cell_log = 0
|
||||
for (mtu >> uint(cell_log)) > 255 {
|
||||
cell_log++
|
||||
}
|
||||
}
|
||||
for i := 0; i < 256; i++ {
|
||||
sz = AdjustSize(uint((i+1)<<uint32(cell_log)), uint(mpu), linklayer)
|
||||
rtab[i] = uint32(Xmittime(uint64(bps), uint32(sz)))
|
||||
}
|
||||
rate.CellAlign = -1
|
||||
rate.CellLog = uint8(cell_log)
|
||||
rate.Linklayer = uint8(linklayer & nl.TC_LINKLAYER_MASK)
|
||||
return cell_log
|
||||
}
|
||||
|
||||
func DeserializeRtab(b []byte) [256]uint32 {
|
||||
var rtab [256]uint32
|
||||
native := nl.NativeEndian()
|
||||
r := bytes.NewReader(b)
|
||||
_ = binary.Read(r, native, &rtab)
|
||||
return rtab
|
||||
}
|
||||
|
||||
func SerializeRtab(rtab [256]uint32) []byte {
|
||||
native := nl.NativeEndian()
|
||||
var w bytes.Buffer
|
||||
_ = binary.Write(&w, native, rtab)
|
||||
return w.Bytes()
|
||||
}
|
56
libnetwork/Godeps/_workspace/src/github.com/vishvananda/netlink/link.go
generated
vendored
56
libnetwork/Godeps/_workspace/src/github.com/vishvananda/netlink/link.go
generated
vendored
|
@ -1,6 +1,9 @@
|
|||
package netlink
|
||||
|
||||
import "net"
|
||||
import (
|
||||
"net"
|
||||
"syscall"
|
||||
)
|
||||
|
||||
// Link represents a link device from netlink. Shared link attributes
|
||||
// like name may be retrieved using the Attrs() method. Unique data
|
||||
|
@ -62,6 +65,19 @@ func (dummy *Dummy) Type() string {
|
|||
return "dummy"
|
||||
}
|
||||
|
||||
// Ifb links are advanced dummy devices for packet filtering
|
||||
type Ifb struct {
|
||||
LinkAttrs
|
||||
}
|
||||
|
||||
func (ifb *Ifb) Attrs() *LinkAttrs {
|
||||
return &ifb.LinkAttrs
|
||||
}
|
||||
|
||||
func (ifb *Ifb) Type() string {
|
||||
return "ifb"
|
||||
}
|
||||
|
||||
// Bridge links are simple linux bridges
|
||||
type Bridge struct {
|
||||
LinkAttrs
|
||||
|
@ -114,6 +130,36 @@ func (macvlan *Macvlan) Type() string {
|
|||
return "macvlan"
|
||||
}
|
||||
|
||||
// Macvtap - macvtap is a virtual interfaces based on macvlan
|
||||
type Macvtap struct {
|
||||
Macvlan
|
||||
}
|
||||
|
||||
func (macvtap Macvtap) Type() string {
|
||||
return "macvtap"
|
||||
}
|
||||
|
||||
type TuntapMode uint16
|
||||
|
||||
const (
|
||||
TUNTAP_MODE_TUN TuntapMode = syscall.IFF_TUN
|
||||
TUNTAP_MODE_TAP TuntapMode = syscall.IFF_TAP
|
||||
)
|
||||
|
||||
// Tuntap links created via /dev/tun/tap, but can be destroyed via netlink
|
||||
type Tuntap struct {
|
||||
LinkAttrs
|
||||
Mode TuntapMode
|
||||
}
|
||||
|
||||
func (tuntap *Tuntap) Attrs() *LinkAttrs {
|
||||
return &tuntap.LinkAttrs
|
||||
}
|
||||
|
||||
func (tuntap *Tuntap) Type() string {
|
||||
return "tuntap"
|
||||
}
|
||||
|
||||
// Veth devices must specify PeerName on create
|
||||
type Veth struct {
|
||||
LinkAttrs
|
||||
|
@ -128,18 +174,18 @@ func (veth *Veth) Type() string {
|
|||
return "veth"
|
||||
}
|
||||
|
||||
// Generic links represent types that are not currently understood
|
||||
// GenericLink links represent types that are not currently understood
|
||||
// by this netlink library.
|
||||
type Generic struct {
|
||||
type GenericLink struct {
|
||||
LinkAttrs
|
||||
LinkType string
|
||||
}
|
||||
|
||||
func (generic *Generic) Attrs() *LinkAttrs {
|
||||
func (generic *GenericLink) Attrs() *LinkAttrs {
|
||||
return &generic.LinkAttrs
|
||||
}
|
||||
|
||||
func (generic *Generic) Type() string {
|
||||
func (generic *GenericLink) Type() string {
|
||||
return generic.LinkType
|
||||
}
|
||||
|
||||
|
|
93
libnetwork/Godeps/_workspace/src/github.com/vishvananda/netlink/link_linux.go
generated
vendored
93
libnetwork/Godeps/_workspace/src/github.com/vishvananda/netlink/link_linux.go
generated
vendored
|
@ -5,7 +5,9 @@ import (
|
|||
"encoding/binary"
|
||||
"fmt"
|
||||
"net"
|
||||
"os"
|
||||
"syscall"
|
||||
"unsafe"
|
||||
|
||||
"github.com/vishvananda/netlink/nl"
|
||||
)
|
||||
|
@ -285,6 +287,44 @@ func LinkAdd(link Link) error {
|
|||
return fmt.Errorf("LinkAttrs.Name cannot be empty!")
|
||||
}
|
||||
|
||||
if tuntap, ok := link.(*Tuntap); ok {
|
||||
// TODO: support user
|
||||
// TODO: support group
|
||||
// TODO: support non- one_queue
|
||||
// TODO: support pi | vnet_hdr | multi_queue
|
||||
// TODO: support non- exclusive
|
||||
// TODO: support non- persistent
|
||||
if tuntap.Mode < syscall.IFF_TUN || tuntap.Mode > syscall.IFF_TAP {
|
||||
return fmt.Errorf("Tuntap.Mode %v unknown!", tuntap.Mode)
|
||||
}
|
||||
file, err := os.OpenFile("/dev/net/tun", os.O_RDWR, 0)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer file.Close()
|
||||
var req ifReq
|
||||
req.Flags |= syscall.IFF_ONE_QUEUE
|
||||
req.Flags |= syscall.IFF_TUN_EXCL
|
||||
copy(req.Name[:15], base.Name)
|
||||
req.Flags |= uint16(tuntap.Mode)
|
||||
_, _, errno := syscall.Syscall(syscall.SYS_IOCTL, file.Fd(), uintptr(syscall.TUNSETIFF), uintptr(unsafe.Pointer(&req)))
|
||||
if errno != 0 {
|
||||
return fmt.Errorf("Tuntap IOCTL TUNSETIFF failed, errno %v", errno)
|
||||
}
|
||||
_, _, errno = syscall.Syscall(syscall.SYS_IOCTL, file.Fd(), uintptr(syscall.TUNSETPERSIST), 1)
|
||||
if errno != 0 {
|
||||
return fmt.Errorf("Tuntap IOCTL TUNSETPERSIST failed, errno %v", errno)
|
||||
}
|
||||
ensureIndex(base)
|
||||
|
||||
// can't set master during create, so set it afterwards
|
||||
if base.MasterIndex != 0 {
|
||||
// TODO: verify MasterIndex is actually a bridge?
|
||||
return LinkSetMasterByIndex(link, base.MasterIndex)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
req := nl.NewNetlinkRequest(syscall.RTM_NEWLINK, syscall.NLM_F_CREATE|syscall.NLM_F_EXCL|syscall.NLM_F_ACK)
|
||||
|
||||
msg := nl.NewIfInfomsg(syscall.AF_UNSPEC)
|
||||
|
@ -493,6 +533,8 @@ func linkDeserialize(m []byte) (Link, error) {
|
|||
switch linkType {
|
||||
case "dummy":
|
||||
link = &Dummy{}
|
||||
case "ifb":
|
||||
link = &Ifb{}
|
||||
case "bridge":
|
||||
link = &Bridge{}
|
||||
case "vlan":
|
||||
|
@ -505,8 +547,10 @@ func linkDeserialize(m []byte) (Link, error) {
|
|||
link = &IPVlan{}
|
||||
case "macvlan":
|
||||
link = &Macvlan{}
|
||||
case "macvtap":
|
||||
link = &Macvtap{}
|
||||
default:
|
||||
link = &Generic{LinkType: linkType}
|
||||
link = &GenericLink{LinkType: linkType}
|
||||
}
|
||||
case nl.IFLA_INFO_DATA:
|
||||
data, err := nl.ParseRouteAttr(info.Value)
|
||||
|
@ -522,6 +566,8 @@ func linkDeserialize(m []byte) (Link, error) {
|
|||
parseIPVlanData(link, data)
|
||||
case "macvlan":
|
||||
parseMacvlanData(link, data)
|
||||
case "macvtap":
|
||||
parseMacvtapData(link, data)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -583,6 +629,46 @@ func LinkList() ([]Link, error) {
|
|||
return res, nil
|
||||
}
|
||||
|
||||
// LinkUpdate is used to pass information back from LinkSubscribe()
|
||||
type LinkUpdate struct {
|
||||
nl.IfInfomsg
|
||||
Link
|
||||
}
|
||||
|
||||
// LinkSubscribe takes a chan down which notifications will be sent
|
||||
// when links change. Close the 'done' chan to stop subscription.
|
||||
func LinkSubscribe(ch chan<- LinkUpdate, done <-chan struct{}) error {
|
||||
s, err := nl.Subscribe(syscall.NETLINK_ROUTE, syscall.RTNLGRP_LINK)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if done != nil {
|
||||
go func() {
|
||||
<-done
|
||||
s.Close()
|
||||
}()
|
||||
}
|
||||
go func() {
|
||||
defer close(ch)
|
||||
for {
|
||||
msgs, err := s.Receive()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
for _, m := range msgs {
|
||||
ifmsg := nl.DeserializeIfInfomsg(m.Data)
|
||||
link, err := linkDeserialize(m.Data)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
ch <- LinkUpdate{IfInfomsg: *ifmsg, Link: link}
|
||||
}
|
||||
}
|
||||
}()
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func LinkSetHairpin(link Link, mode bool) error {
|
||||
return setProtinfoAttr(link, mode, nl.IFLA_BRPORT_MODE)
|
||||
}
|
||||
|
@ -696,6 +782,11 @@ func parseIPVlanData(link Link, data []syscall.NetlinkRouteAttr) {
|
|||
}
|
||||
}
|
||||
|
||||
func parseMacvtapData(link Link, data []syscall.NetlinkRouteAttr) {
|
||||
macv := link.(*Macvtap)
|
||||
parseMacvlanData(&macv.Macvlan, data)
|
||||
}
|
||||
|
||||
func parseMacvlanData(link Link, data []syscall.NetlinkRouteAttr) {
|
||||
macv := link.(*Macvlan)
|
||||
for _, datum := range data {
|
||||
|
|
643
libnetwork/Godeps/_workspace/src/github.com/vishvananda/netlink/link_test.go
generated
vendored
643
libnetwork/Godeps/_workspace/src/github.com/vishvananda/netlink/link_test.go
generated
vendored
|
@ -1,643 +0,0 @@
|
|||
package netlink
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"net"
|
||||
"testing"
|
||||
|
||||
"github.com/vishvananda/netns"
|
||||
)
|
||||
|
||||
const (
|
||||
testTxQLen int = 100
|
||||
defaultTxQLen int = 1000
|
||||
)
|
||||
|
||||
func testLinkAddDel(t *testing.T, link Link) {
|
||||
links, err := LinkList()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
num := len(links)
|
||||
|
||||
if err := LinkAdd(link); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
base := link.Attrs()
|
||||
|
||||
result, err := LinkByName(base.Name)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
rBase := result.Attrs()
|
||||
|
||||
if vlan, ok := link.(*Vlan); ok {
|
||||
other, ok := result.(*Vlan)
|
||||
if !ok {
|
||||
t.Fatal("Result of create is not a vlan")
|
||||
}
|
||||
if vlan.VlanId != other.VlanId {
|
||||
t.Fatal("Link.VlanId id doesn't match")
|
||||
}
|
||||
}
|
||||
|
||||
if rBase.ParentIndex == 0 && base.ParentIndex != 0 {
|
||||
t.Fatal("Created link doesn't have a Parent but it should")
|
||||
} else if rBase.ParentIndex != 0 && base.ParentIndex == 0 {
|
||||
t.Fatal("Created link has a Parent but it shouldn't")
|
||||
} else if rBase.ParentIndex != 0 && base.ParentIndex != 0 {
|
||||
if rBase.ParentIndex != base.ParentIndex {
|
||||
t.Fatal("Link.ParentIndex doesn't match")
|
||||
}
|
||||
}
|
||||
|
||||
if veth, ok := result.(*Veth); ok {
|
||||
if rBase.TxQLen != base.TxQLen {
|
||||
t.Fatalf("qlen is %d, should be %d", rBase.TxQLen, base.TxQLen)
|
||||
}
|
||||
if rBase.MTU != base.MTU {
|
||||
t.Fatalf("MTU is %d, should be %d", rBase.MTU, base.MTU)
|
||||
}
|
||||
|
||||
if veth.PeerName != "" {
|
||||
var peer *Veth
|
||||
other, err := LinkByName(veth.PeerName)
|
||||
if err != nil {
|
||||
t.Fatalf("Peer %s not created", veth.PeerName)
|
||||
}
|
||||
if peer, ok = other.(*Veth); !ok {
|
||||
t.Fatalf("Peer %s is incorrect type", veth.PeerName)
|
||||
}
|
||||
if peer.TxQLen != testTxQLen {
|
||||
t.Fatalf("TxQLen of peer is %d, should be %d", peer.TxQLen, testTxQLen)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if vxlan, ok := link.(*Vxlan); ok {
|
||||
other, ok := result.(*Vxlan)
|
||||
if !ok {
|
||||
t.Fatal("Result of create is not a vxlan")
|
||||
}
|
||||
compareVxlan(t, vxlan, other)
|
||||
}
|
||||
|
||||
if ipv, ok := link.(*IPVlan); ok {
|
||||
other, ok := result.(*IPVlan)
|
||||
if !ok {
|
||||
t.Fatal("Result of create is not a ipvlan")
|
||||
}
|
||||
if ipv.Mode != other.Mode {
|
||||
t.Fatalf("Got unexpected mode: %d, expected: %d", other.Mode, ipv.Mode)
|
||||
}
|
||||
}
|
||||
|
||||
if macv, ok := link.(*Macvlan); ok {
|
||||
other, ok := result.(*Macvlan)
|
||||
if !ok {
|
||||
t.Fatal("Result of create is not a macvlan")
|
||||
}
|
||||
if macv.Mode != other.Mode {
|
||||
t.Fatalf("Got unexpected mode: %d, expected: %d", other.Mode, macv.Mode)
|
||||
}
|
||||
}
|
||||
|
||||
if err = LinkDel(link); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
links, err = LinkList()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if len(links) != num {
|
||||
t.Fatal("Link not removed properly")
|
||||
}
|
||||
}
|
||||
|
||||
func compareVxlan(t *testing.T, expected, actual *Vxlan) {
|
||||
|
||||
if actual.VxlanId != expected.VxlanId {
|
||||
t.Fatal("Vxlan.VxlanId doesn't match")
|
||||
}
|
||||
if expected.SrcAddr != nil && !actual.SrcAddr.Equal(expected.SrcAddr) {
|
||||
t.Fatal("Vxlan.SrcAddr doesn't match")
|
||||
}
|
||||
if expected.Group != nil && !actual.Group.Equal(expected.Group) {
|
||||
t.Fatal("Vxlan.Group doesn't match")
|
||||
}
|
||||
if expected.TTL != -1 && actual.TTL != expected.TTL {
|
||||
t.Fatal("Vxlan.TTL doesn't match")
|
||||
}
|
||||
if expected.TOS != -1 && actual.TOS != expected.TOS {
|
||||
t.Fatal("Vxlan.TOS doesn't match")
|
||||
}
|
||||
if actual.Learning != expected.Learning {
|
||||
t.Fatal("Vxlan.Learning doesn't match")
|
||||
}
|
||||
if actual.Proxy != expected.Proxy {
|
||||
t.Fatal("Vxlan.Proxy doesn't match")
|
||||
}
|
||||
if actual.RSC != expected.RSC {
|
||||
t.Fatal("Vxlan.RSC doesn't match")
|
||||
}
|
||||
if actual.L2miss != expected.L2miss {
|
||||
t.Fatal("Vxlan.L2miss doesn't match")
|
||||
}
|
||||
if actual.L3miss != expected.L3miss {
|
||||
t.Fatal("Vxlan.L3miss doesn't match")
|
||||
}
|
||||
if actual.GBP != expected.GBP {
|
||||
t.Fatal("Vxlan.GBP doesn't match")
|
||||
}
|
||||
if expected.NoAge {
|
||||
if !actual.NoAge {
|
||||
t.Fatal("Vxlan.NoAge doesn't match")
|
||||
}
|
||||
} else if expected.Age > 0 && actual.Age != expected.Age {
|
||||
t.Fatal("Vxlan.Age doesn't match")
|
||||
}
|
||||
if expected.Limit > 0 && actual.Limit != expected.Limit {
|
||||
t.Fatal("Vxlan.Limit doesn't match")
|
||||
}
|
||||
if expected.Port > 0 && actual.Port != expected.Port {
|
||||
t.Fatal("Vxlan.Port doesn't match")
|
||||
}
|
||||
if expected.PortLow > 0 || expected.PortHigh > 0 {
|
||||
if actual.PortLow != expected.PortLow {
|
||||
t.Fatal("Vxlan.PortLow doesn't match")
|
||||
}
|
||||
if actual.PortHigh != expected.PortHigh {
|
||||
t.Fatal("Vxlan.PortHigh doesn't match")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestLinkAddDelDummy(t *testing.T) {
|
||||
tearDown := setUpNetlinkTest(t)
|
||||
defer tearDown()
|
||||
|
||||
testLinkAddDel(t, &Dummy{LinkAttrs{Name: "foo"}})
|
||||
}
|
||||
|
||||
func TestLinkAddDelBridge(t *testing.T) {
|
||||
tearDown := setUpNetlinkTest(t)
|
||||
defer tearDown()
|
||||
|
||||
testLinkAddDel(t, &Bridge{LinkAttrs{Name: "foo", MTU: 1400}})
|
||||
}
|
||||
|
||||
func TestLinkAddDelVlan(t *testing.T) {
|
||||
tearDown := setUpNetlinkTest(t)
|
||||
defer tearDown()
|
||||
|
||||
parent := &Dummy{LinkAttrs{Name: "foo"}}
|
||||
if err := LinkAdd(parent); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
testLinkAddDel(t, &Vlan{LinkAttrs{Name: "bar", ParentIndex: parent.Attrs().Index}, 900})
|
||||
|
||||
if err := LinkDel(parent); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestLinkAddDelMacvlan(t *testing.T) {
|
||||
tearDown := setUpNetlinkTest(t)
|
||||
defer tearDown()
|
||||
|
||||
parent := &Dummy{LinkAttrs{Name: "foo"}}
|
||||
if err := LinkAdd(parent); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
testLinkAddDel(t, &Macvlan{
|
||||
LinkAttrs: LinkAttrs{Name: "bar", ParentIndex: parent.Attrs().Index},
|
||||
Mode: MACVLAN_MODE_PRIVATE,
|
||||
})
|
||||
|
||||
if err := LinkDel(parent); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestLinkAddDelVeth(t *testing.T) {
|
||||
tearDown := setUpNetlinkTest(t)
|
||||
defer tearDown()
|
||||
|
||||
testLinkAddDel(t, &Veth{LinkAttrs{Name: "foo", TxQLen: testTxQLen, MTU: 1400}, "bar"})
|
||||
}
|
||||
|
||||
func TestLinkAddVethWithDefaultTxQLen(t *testing.T) {
|
||||
tearDown := setUpNetlinkTest(t)
|
||||
defer tearDown()
|
||||
la := NewLinkAttrs()
|
||||
la.Name = "foo"
|
||||
|
||||
veth := &Veth{LinkAttrs: la, PeerName: "bar"}
|
||||
if err := LinkAdd(veth); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
link, err := LinkByName("foo")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if veth, ok := link.(*Veth); !ok {
|
||||
t.Fatalf("unexpected link type: %T", link)
|
||||
} else {
|
||||
if veth.TxQLen != defaultTxQLen {
|
||||
t.Fatalf("TxQLen is %d, should be %d", veth.TxQLen, defaultTxQLen)
|
||||
}
|
||||
}
|
||||
peer, err := LinkByName("bar")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if veth, ok := peer.(*Veth); !ok {
|
||||
t.Fatalf("unexpected link type: %T", link)
|
||||
} else {
|
||||
if veth.TxQLen != defaultTxQLen {
|
||||
t.Fatalf("TxQLen is %d, should be %d", veth.TxQLen, defaultTxQLen)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestLinkAddVethWithZeroTxQLen(t *testing.T) {
|
||||
tearDown := setUpNetlinkTest(t)
|
||||
defer tearDown()
|
||||
la := NewLinkAttrs()
|
||||
la.Name = "foo"
|
||||
la.TxQLen = 0
|
||||
|
||||
veth := &Veth{LinkAttrs: la, PeerName: "bar"}
|
||||
if err := LinkAdd(veth); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
link, err := LinkByName("foo")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if veth, ok := link.(*Veth); !ok {
|
||||
t.Fatalf("unexpected link type: %T", link)
|
||||
} else {
|
||||
if veth.TxQLen != 0 {
|
||||
t.Fatalf("TxQLen is %d, should be %d", veth.TxQLen, 0)
|
||||
}
|
||||
}
|
||||
peer, err := LinkByName("bar")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if veth, ok := peer.(*Veth); !ok {
|
||||
t.Fatalf("unexpected link type: %T", link)
|
||||
} else {
|
||||
if veth.TxQLen != 0 {
|
||||
t.Fatalf("TxQLen is %d, should be %d", veth.TxQLen, 0)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestLinkAddDummyWithTxQLen(t *testing.T) {
|
||||
tearDown := setUpNetlinkTest(t)
|
||||
defer tearDown()
|
||||
la := NewLinkAttrs()
|
||||
la.Name = "foo"
|
||||
la.TxQLen = 1500
|
||||
|
||||
dummy := &Dummy{LinkAttrs: la}
|
||||
if err := LinkAdd(dummy); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
link, err := LinkByName("foo")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if dummy, ok := link.(*Dummy); !ok {
|
||||
t.Fatalf("unexpected link type: %T", link)
|
||||
} else {
|
||||
if dummy.TxQLen != 1500 {
|
||||
t.Fatalf("TxQLen is %d, should be %d", dummy.TxQLen, 1500)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestLinkAddDelBridgeMaster(t *testing.T) {
|
||||
tearDown := setUpNetlinkTest(t)
|
||||
defer tearDown()
|
||||
|
||||
master := &Bridge{LinkAttrs{Name: "foo"}}
|
||||
if err := LinkAdd(master); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
testLinkAddDel(t, &Dummy{LinkAttrs{Name: "bar", MasterIndex: master.Attrs().Index}})
|
||||
|
||||
if err := LinkDel(master); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestLinkSetUnsetResetMaster(t *testing.T) {
|
||||
tearDown := setUpNetlinkTest(t)
|
||||
defer tearDown()
|
||||
|
||||
master := &Bridge{LinkAttrs{Name: "foo"}}
|
||||
if err := LinkAdd(master); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
newmaster := &Bridge{LinkAttrs{Name: "bar"}}
|
||||
if err := LinkAdd(newmaster); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
slave := &Dummy{LinkAttrs{Name: "baz"}}
|
||||
if err := LinkAdd(slave); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if err := LinkSetMaster(slave, master); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
link, err := LinkByName("baz")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if link.Attrs().MasterIndex != master.Attrs().Index {
|
||||
t.Fatal("Master not set properly")
|
||||
}
|
||||
|
||||
if err := LinkSetMaster(slave, newmaster); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
link, err = LinkByName("baz")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if link.Attrs().MasterIndex != newmaster.Attrs().Index {
|
||||
t.Fatal("Master not reset properly")
|
||||
}
|
||||
|
||||
if err := LinkSetMaster(slave, nil); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
link, err = LinkByName("baz")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if link.Attrs().MasterIndex != 0 {
|
||||
t.Fatal("Master not unset properly")
|
||||
}
|
||||
if err := LinkDel(slave); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if err := LinkDel(newmaster); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if err := LinkDel(master); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestLinkSetNs(t *testing.T) {
|
||||
tearDown := setUpNetlinkTest(t)
|
||||
defer tearDown()
|
||||
|
||||
basens, err := netns.Get()
|
||||
if err != nil {
|
||||
t.Fatal("Failed to get basens")
|
||||
}
|
||||
defer basens.Close()
|
||||
|
||||
newns, err := netns.New()
|
||||
if err != nil {
|
||||
t.Fatal("Failed to create newns")
|
||||
}
|
||||
defer newns.Close()
|
||||
|
||||
link := &Veth{LinkAttrs{Name: "foo"}, "bar"}
|
||||
if err := LinkAdd(link); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
peer, err := LinkByName("bar")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
LinkSetNsFd(peer, int(basens))
|
||||
if err != nil {
|
||||
t.Fatal("Failed to set newns for link")
|
||||
}
|
||||
|
||||
_, err = LinkByName("bar")
|
||||
if err == nil {
|
||||
t.Fatal("Link bar is still in newns")
|
||||
}
|
||||
|
||||
err = netns.Set(basens)
|
||||
if err != nil {
|
||||
t.Fatal("Failed to set basens")
|
||||
}
|
||||
|
||||
peer, err = LinkByName("bar")
|
||||
if err != nil {
|
||||
t.Fatal("Link is not in basens")
|
||||
}
|
||||
|
||||
if err := LinkDel(peer); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
err = netns.Set(newns)
|
||||
if err != nil {
|
||||
t.Fatal("Failed to set newns")
|
||||
}
|
||||
|
||||
_, err = LinkByName("foo")
|
||||
if err == nil {
|
||||
t.Fatal("Other half of veth pair not deleted")
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func TestLinkAddDelVxlan(t *testing.T) {
|
||||
tearDown := setUpNetlinkTest(t)
|
||||
defer tearDown()
|
||||
|
||||
parent := &Dummy{
|
||||
LinkAttrs{Name: "foo"},
|
||||
}
|
||||
if err := LinkAdd(parent); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
vxlan := Vxlan{
|
||||
LinkAttrs: LinkAttrs{
|
||||
Name: "bar",
|
||||
},
|
||||
VxlanId: 10,
|
||||
VtepDevIndex: parent.Index,
|
||||
Learning: true,
|
||||
L2miss: true,
|
||||
L3miss: true,
|
||||
}
|
||||
|
||||
testLinkAddDel(t, &vxlan)
|
||||
if err := LinkDel(parent); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestLinkAddDelIPVlanL2(t *testing.T) {
|
||||
tearDown := setUpNetlinkTest(t)
|
||||
defer tearDown()
|
||||
parent := &Dummy{LinkAttrs{Name: "foo"}}
|
||||
if err := LinkAdd(parent); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
ipv := IPVlan{
|
||||
LinkAttrs: LinkAttrs{
|
||||
Name: "bar",
|
||||
ParentIndex: parent.Index,
|
||||
},
|
||||
Mode: IPVLAN_MODE_L2,
|
||||
}
|
||||
|
||||
testLinkAddDel(t, &ipv)
|
||||
}
|
||||
|
||||
func TestLinkAddDelIPVlanL3(t *testing.T) {
|
||||
tearDown := setUpNetlinkTest(t)
|
||||
defer tearDown()
|
||||
parent := &Dummy{LinkAttrs{Name: "foo"}}
|
||||
if err := LinkAdd(parent); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
ipv := IPVlan{
|
||||
LinkAttrs: LinkAttrs{
|
||||
Name: "bar",
|
||||
ParentIndex: parent.Index,
|
||||
},
|
||||
Mode: IPVLAN_MODE_L3,
|
||||
}
|
||||
|
||||
testLinkAddDel(t, &ipv)
|
||||
}
|
||||
|
||||
func TestLinkAddDelIPVlanNoParent(t *testing.T) {
|
||||
tearDown := setUpNetlinkTest(t)
|
||||
defer tearDown()
|
||||
|
||||
ipv := IPVlan{
|
||||
LinkAttrs: LinkAttrs{
|
||||
Name: "bar",
|
||||
},
|
||||
Mode: IPVLAN_MODE_L3,
|
||||
}
|
||||
err := LinkAdd(&ipv)
|
||||
if err == nil {
|
||||
t.Fatal("Add should fail if ipvlan creating without ParentIndex")
|
||||
}
|
||||
if err.Error() != "Can't create ipvlan link without ParentIndex" {
|
||||
t.Fatalf("Error should be about missing ParentIndex, got %q", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestLinkByIndex(t *testing.T) {
|
||||
tearDown := setUpNetlinkTest(t)
|
||||
defer tearDown()
|
||||
|
||||
dummy := &Dummy{LinkAttrs{Name: "dummy"}}
|
||||
if err := LinkAdd(dummy); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
found, err := LinkByIndex(dummy.Index)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if found.Attrs().Index != dummy.Attrs().Index {
|
||||
t.Fatalf("Indices don't match: %v != %v", found.Attrs().Index, dummy.Attrs().Index)
|
||||
}
|
||||
|
||||
LinkDel(dummy)
|
||||
|
||||
// test not found
|
||||
_, err = LinkByIndex(dummy.Attrs().Index)
|
||||
if err == nil {
|
||||
t.Fatalf("LinkByIndex(%v) found deleted link", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestLinkSet(t *testing.T) {
|
||||
tearDown := setUpNetlinkTest(t)
|
||||
defer tearDown()
|
||||
|
||||
iface := &Dummy{LinkAttrs{Name: "foo"}}
|
||||
if err := LinkAdd(iface); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
link, err := LinkByName("foo")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
err = LinkSetName(link, "bar")
|
||||
if err != nil {
|
||||
t.Fatalf("Could not change interface name: %v", err)
|
||||
}
|
||||
|
||||
link, err = LinkByName("bar")
|
||||
if err != nil {
|
||||
t.Fatalf("Interface name not changed: %v", err)
|
||||
}
|
||||
|
||||
err = LinkSetMTU(link, 1400)
|
||||
if err != nil {
|
||||
t.Fatalf("Could not set MTU: %v", err)
|
||||
}
|
||||
|
||||
link, err = LinkByName("bar")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if link.Attrs().MTU != 1400 {
|
||||
t.Fatal("MTU not changed!")
|
||||
}
|
||||
|
||||
addr, err := net.ParseMAC("00:12:34:56:78:AB")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
err = LinkSetHardwareAddr(link, addr)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
link, err = LinkByName("bar")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if !bytes.Equal(link.Attrs().HardwareAddr, addr) {
|
||||
t.Fatalf("hardware address not changed!")
|
||||
}
|
||||
}
|
14
libnetwork/Godeps/_workspace/src/github.com/vishvananda/netlink/link_tuntap_linux.go
generated
vendored
Normal file
14
libnetwork/Godeps/_workspace/src/github.com/vishvananda/netlink/link_tuntap_linux.go
generated
vendored
Normal file
|
@ -0,0 +1,14 @@
|
|||
package netlink
|
||||
|
||||
// ideally golang.org/x/sys/unix would define IfReq but it only has
|
||||
// IFNAMSIZ, hence this minimalistic implementation
|
||||
const (
|
||||
SizeOfIfReq = 40
|
||||
IFNAMSIZ = 16
|
||||
)
|
||||
|
||||
type ifReq struct {
|
||||
Name [IFNAMSIZ]byte
|
||||
Flags uint16
|
||||
pad [SizeOfIfReq - IFNAMSIZ - 2]byte
|
||||
}
|
104
libnetwork/Godeps/_workspace/src/github.com/vishvananda/netlink/neigh_test.go
generated
vendored
104
libnetwork/Godeps/_workspace/src/github.com/vishvananda/netlink/neigh_test.go
generated
vendored
|
@ -1,104 +0,0 @@
|
|||
package netlink
|
||||
|
||||
import (
|
||||
"net"
|
||||
"testing"
|
||||
)
|
||||
|
||||
type arpEntry struct {
|
||||
ip net.IP
|
||||
mac net.HardwareAddr
|
||||
}
|
||||
|
||||
func parseMAC(s string) net.HardwareAddr {
|
||||
m, err := net.ParseMAC(s)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return m
|
||||
}
|
||||
|
||||
func dumpContains(dump []Neigh, e arpEntry) bool {
|
||||
for _, n := range dump {
|
||||
if n.IP.Equal(e.ip) && (n.State&NUD_INCOMPLETE) == 0 {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func TestNeighAddDel(t *testing.T) {
|
||||
tearDown := setUpNetlinkTest(t)
|
||||
defer tearDown()
|
||||
|
||||
dummy := Dummy{LinkAttrs{Name: "neigh0"}}
|
||||
if err := LinkAdd(&dummy); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
ensureIndex(dummy.Attrs())
|
||||
|
||||
arpTable := []arpEntry{
|
||||
{net.ParseIP("10.99.0.1"), parseMAC("aa:bb:cc:dd:00:01")},
|
||||
{net.ParseIP("10.99.0.2"), parseMAC("aa:bb:cc:dd:00:02")},
|
||||
{net.ParseIP("10.99.0.3"), parseMAC("aa:bb:cc:dd:00:03")},
|
||||
{net.ParseIP("10.99.0.4"), parseMAC("aa:bb:cc:dd:00:04")},
|
||||
{net.ParseIP("10.99.0.5"), parseMAC("aa:bb:cc:dd:00:05")},
|
||||
}
|
||||
|
||||
// Add the arpTable
|
||||
for _, entry := range arpTable {
|
||||
err := NeighAdd(&Neigh{
|
||||
LinkIndex: dummy.Index,
|
||||
State: NUD_REACHABLE,
|
||||
IP: entry.ip,
|
||||
HardwareAddr: entry.mac,
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
t.Errorf("Failed to NeighAdd: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
// Dump and see that all added entries are there
|
||||
dump, err := NeighList(dummy.Index, 0)
|
||||
if err != nil {
|
||||
t.Errorf("Failed to NeighList: %v", err)
|
||||
}
|
||||
|
||||
for _, entry := range arpTable {
|
||||
if !dumpContains(dump, entry) {
|
||||
t.Errorf("Dump does not contain: %v", entry)
|
||||
}
|
||||
}
|
||||
|
||||
// Delete the arpTable
|
||||
for _, entry := range arpTable {
|
||||
err := NeighDel(&Neigh{
|
||||
LinkIndex: dummy.Index,
|
||||
IP: entry.ip,
|
||||
HardwareAddr: entry.mac,
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
t.Errorf("Failed to NeighDel: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: seems not working because of cache
|
||||
//// Dump and see that none of deleted entries are there
|
||||
//dump, err = NeighList(dummy.Index, 0)
|
||||
//if err != nil {
|
||||
//t.Errorf("Failed to NeighList: %v", err)
|
||||
//}
|
||||
|
||||
//for _, entry := range arpTable {
|
||||
//if dumpContains(dump, entry) {
|
||||
//t.Errorf("Dump contains: %v", entry)
|
||||
//}
|
||||
//}
|
||||
|
||||
if err := LinkDel(&dummy); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
34
libnetwork/Godeps/_workspace/src/github.com/vishvananda/netlink/netlink_test.go
generated
vendored
34
libnetwork/Godeps/_workspace/src/github.com/vishvananda/netlink/netlink_test.go
generated
vendored
|
@ -1,34 +0,0 @@
|
|||
package netlink
|
||||
|
||||
import (
|
||||
"log"
|
||||
"os"
|
||||
"runtime"
|
||||
"testing"
|
||||
|
||||
"github.com/vishvananda/netns"
|
||||
)
|
||||
|
||||
type tearDownNetlinkTest func()
|
||||
|
||||
func setUpNetlinkTest(t *testing.T) tearDownNetlinkTest {
|
||||
if os.Getuid() != 0 {
|
||||
msg := "Skipped test because it requires root privileges."
|
||||
log.Printf(msg)
|
||||
t.Skip(msg)
|
||||
}
|
||||
|
||||
// new temporary namespace so we don't pollute the host
|
||||
// lock thread since the namespace is thread local
|
||||
runtime.LockOSThread()
|
||||
var err error
|
||||
ns, err := netns.New()
|
||||
if err != nil {
|
||||
t.Fatal("Failed to create newns", ns)
|
||||
}
|
||||
|
||||
return func() {
|
||||
ns.Close()
|
||||
runtime.UnlockOSThread()
|
||||
}
|
||||
}
|
39
libnetwork/Godeps/_workspace/src/github.com/vishvananda/netlink/nl/addr_linux_test.go
generated
vendored
39
libnetwork/Godeps/_workspace/src/github.com/vishvananda/netlink/nl/addr_linux_test.go
generated
vendored
|
@ -1,39 +0,0 @@
|
|||
package nl
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"crypto/rand"
|
||||
"encoding/binary"
|
||||
"syscall"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func (msg *IfAddrmsg) write(b []byte) {
|
||||
native := NativeEndian()
|
||||
b[0] = msg.Family
|
||||
b[1] = msg.Prefixlen
|
||||
b[2] = msg.Flags
|
||||
b[3] = msg.Scope
|
||||
native.PutUint32(b[4:8], msg.Index)
|
||||
}
|
||||
|
||||
func (msg *IfAddrmsg) serializeSafe() []byte {
|
||||
len := syscall.SizeofIfAddrmsg
|
||||
b := make([]byte, len)
|
||||
msg.write(b)
|
||||
return b
|
||||
}
|
||||
|
||||
func deserializeIfAddrmsgSafe(b []byte) *IfAddrmsg {
|
||||
var msg = IfAddrmsg{}
|
||||
binary.Read(bytes.NewReader(b[0:syscall.SizeofIfAddrmsg]), NativeEndian(), &msg)
|
||||
return &msg
|
||||
}
|
||||
|
||||
func TestIfAddrmsgDeserializeSerialize(t *testing.T) {
|
||||
var orig = make([]byte, syscall.SizeofIfAddrmsg)
|
||||
rand.Read(orig)
|
||||
safemsg := deserializeIfAddrmsgSafe(orig)
|
||||
msg := DeserializeIfAddrmsg(orig)
|
||||
testDeserializeSerialize(t, orig, safemsg, msg)
|
||||
}
|
2
libnetwork/Godeps/_workspace/src/github.com/vishvananda/netlink/nl/nl_linux.go
generated
vendored
2
libnetwork/Godeps/_workspace/src/github.com/vishvananda/netlink/nl/nl_linux.go
generated
vendored
|
@ -142,7 +142,7 @@ func (a *RtAttr) Len() int {
|
|||
}
|
||||
|
||||
// Serialize the RtAttr into a byte array
|
||||
// This can't ust unsafe.cast because it must iterate through children.
|
||||
// This can't just unsafe.cast because it must iterate through children.
|
||||
func (a *RtAttr) Serialize() []byte {
|
||||
native := NativeEndian()
|
||||
|
||||
|
|
60
libnetwork/Godeps/_workspace/src/github.com/vishvananda/netlink/nl/nl_linux_test.go
generated
vendored
60
libnetwork/Godeps/_workspace/src/github.com/vishvananda/netlink/nl/nl_linux_test.go
generated
vendored
|
@ -1,60 +0,0 @@
|
|||
package nl
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"crypto/rand"
|
||||
"encoding/binary"
|
||||
"reflect"
|
||||
"syscall"
|
||||
"testing"
|
||||
)
|
||||
|
||||
type testSerializer interface {
|
||||
serializeSafe() []byte
|
||||
Serialize() []byte
|
||||
}
|
||||
|
||||
func testDeserializeSerialize(t *testing.T, orig []byte, safemsg testSerializer, msg testSerializer) {
|
||||
if !reflect.DeepEqual(safemsg, msg) {
|
||||
t.Fatal("Deserialization failed.\n", safemsg, "\n", msg)
|
||||
}
|
||||
safe := msg.serializeSafe()
|
||||
if !bytes.Equal(safe, orig) {
|
||||
t.Fatal("Safe serialization failed.\n", safe, "\n", orig)
|
||||
}
|
||||
b := msg.Serialize()
|
||||
if !bytes.Equal(b, safe) {
|
||||
t.Fatal("Serialization failed.\n", b, "\n", safe)
|
||||
}
|
||||
}
|
||||
|
||||
func (msg *IfInfomsg) write(b []byte) {
|
||||
native := NativeEndian()
|
||||
b[0] = msg.Family
|
||||
b[1] = msg.X__ifi_pad
|
||||
native.PutUint16(b[2:4], msg.Type)
|
||||
native.PutUint32(b[4:8], uint32(msg.Index))
|
||||
native.PutUint32(b[8:12], msg.Flags)
|
||||
native.PutUint32(b[12:16], msg.Change)
|
||||
}
|
||||
|
||||
func (msg *IfInfomsg) serializeSafe() []byte {
|
||||
length := syscall.SizeofIfInfomsg
|
||||
b := make([]byte, length)
|
||||
msg.write(b)
|
||||
return b
|
||||
}
|
||||
|
||||
func deserializeIfInfomsgSafe(b []byte) *IfInfomsg {
|
||||
var msg = IfInfomsg{}
|
||||
binary.Read(bytes.NewReader(b[0:syscall.SizeofIfInfomsg]), NativeEndian(), &msg)
|
||||
return &msg
|
||||
}
|
||||
|
||||
func TestIfInfomsgDeserializeSerialize(t *testing.T) {
|
||||
var orig = make([]byte, syscall.SizeofIfInfomsg)
|
||||
rand.Read(orig)
|
||||
safemsg := deserializeIfInfomsgSafe(orig)
|
||||
msg := DeserializeIfInfomsg(orig)
|
||||
testDeserializeSerialize(t, orig, safemsg, msg)
|
||||
}
|
43
libnetwork/Godeps/_workspace/src/github.com/vishvananda/netlink/nl/route_linux_test.go
generated
vendored
43
libnetwork/Godeps/_workspace/src/github.com/vishvananda/netlink/nl/route_linux_test.go
generated
vendored
|
@ -1,43 +0,0 @@
|
|||
package nl
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"crypto/rand"
|
||||
"encoding/binary"
|
||||
"syscall"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func (msg *RtMsg) write(b []byte) {
|
||||
native := NativeEndian()
|
||||
b[0] = msg.Family
|
||||
b[1] = msg.Dst_len
|
||||
b[2] = msg.Src_len
|
||||
b[3] = msg.Tos
|
||||
b[4] = msg.Table
|
||||
b[5] = msg.Protocol
|
||||
b[6] = msg.Scope
|
||||
b[7] = msg.Type
|
||||
native.PutUint32(b[8:12], msg.Flags)
|
||||
}
|
||||
|
||||
func (msg *RtMsg) serializeSafe() []byte {
|
||||
len := syscall.SizeofRtMsg
|
||||
b := make([]byte, len)
|
||||
msg.write(b)
|
||||
return b
|
||||
}
|
||||
|
||||
func deserializeRtMsgSafe(b []byte) *RtMsg {
|
||||
var msg = RtMsg{}
|
||||
binary.Read(bytes.NewReader(b[0:syscall.SizeofRtMsg]), NativeEndian(), &msg)
|
||||
return &msg
|
||||
}
|
||||
|
||||
func TestRtMsgDeserializeSerialize(t *testing.T) {
|
||||
var orig = make([]byte, syscall.SizeofRtMsg)
|
||||
rand.Read(orig)
|
||||
safemsg := deserializeRtMsgSafe(orig)
|
||||
msg := DeserializeRtMsg(orig)
|
||||
testDeserializeSerialize(t, orig, safemsg, msg)
|
||||
}
|
508
libnetwork/Godeps/_workspace/src/github.com/vishvananda/netlink/nl/tc_linux.go
generated
vendored
Normal file
508
libnetwork/Godeps/_workspace/src/github.com/vishvananda/netlink/nl/tc_linux.go
generated
vendored
Normal file
|
@ -0,0 +1,508 @@
|
|||
package nl
|
||||
|
||||
import (
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
// LinkLayer
|
||||
const (
|
||||
LINKLAYER_UNSPEC = iota
|
||||
LINKLAYER_ETHERNET
|
||||
LINKLAYER_ATM
|
||||
)
|
||||
|
||||
// ATM
|
||||
const (
|
||||
ATM_CELL_PAYLOAD = 48
|
||||
ATM_CELL_SIZE = 53
|
||||
)
|
||||
|
||||
const TC_LINKLAYER_MASK = 0x0F
|
||||
|
||||
// Police
|
||||
const (
|
||||
TCA_POLICE_UNSPEC = iota
|
||||
TCA_POLICE_TBF
|
||||
TCA_POLICE_RATE
|
||||
TCA_POLICE_PEAKRATE
|
||||
TCA_POLICE_AVRATE
|
||||
TCA_POLICE_RESULT
|
||||
TCA_POLICE_MAX = TCA_POLICE_RESULT
|
||||
)
|
||||
|
||||
// Message types
|
||||
const (
|
||||
TCA_UNSPEC = iota
|
||||
TCA_KIND
|
||||
TCA_OPTIONS
|
||||
TCA_STATS
|
||||
TCA_XSTATS
|
||||
TCA_RATE
|
||||
TCA_FCNT
|
||||
TCA_STATS2
|
||||
TCA_STAB
|
||||
TCA_MAX = TCA_STAB
|
||||
)
|
||||
|
||||
const (
|
||||
TCA_ACT_TAB = 1
|
||||
TCAA_MAX = 1
|
||||
)
|
||||
|
||||
const (
|
||||
TCA_PRIO_UNSPEC = iota
|
||||
TCA_PRIO_MQ
|
||||
TCA_PRIO_MAX = TCA_PRIO_MQ
|
||||
)
|
||||
|
||||
const (
|
||||
SizeofTcMsg = 0x14
|
||||
SizeofTcActionMsg = 0x04
|
||||
SizeofTcPrioMap = 0x14
|
||||
SizeofTcRateSpec = 0x0c
|
||||
SizeofTcTbfQopt = 2*SizeofTcRateSpec + 0x0c
|
||||
SizeofTcHtbCopt = 2*SizeofTcRateSpec + 0x14
|
||||
SizeofTcHtbGlob = 0x14
|
||||
SizeofTcU32Key = 0x10
|
||||
SizeofTcU32Sel = 0x10 // without keys
|
||||
SizeofTcMirred = 0x1c
|
||||
SizeofTcPolice = 2*SizeofTcRateSpec + 0x20
|
||||
)
|
||||
|
||||
// struct tcmsg {
|
||||
// unsigned char tcm_family;
|
||||
// unsigned char tcm__pad1;
|
||||
// unsigned short tcm__pad2;
|
||||
// int tcm_ifindex;
|
||||
// __u32 tcm_handle;
|
||||
// __u32 tcm_parent;
|
||||
// __u32 tcm_info;
|
||||
// };
|
||||
|
||||
type TcMsg struct {
|
||||
Family uint8
|
||||
Pad [3]byte
|
||||
Ifindex int32
|
||||
Handle uint32
|
||||
Parent uint32
|
||||
Info uint32
|
||||
}
|
||||
|
||||
func (msg *TcMsg) Len() int {
|
||||
return SizeofTcMsg
|
||||
}
|
||||
|
||||
func DeserializeTcMsg(b []byte) *TcMsg {
|
||||
return (*TcMsg)(unsafe.Pointer(&b[0:SizeofTcMsg][0]))
|
||||
}
|
||||
|
||||
func (x *TcMsg) Serialize() []byte {
|
||||
return (*(*[SizeofTcMsg]byte)(unsafe.Pointer(x)))[:]
|
||||
}
|
||||
|
||||
// struct tcamsg {
|
||||
// unsigned char tca_family;
|
||||
// unsigned char tca__pad1;
|
||||
// unsigned short tca__pad2;
|
||||
// };
|
||||
|
||||
type TcActionMsg struct {
|
||||
Family uint8
|
||||
Pad [3]byte
|
||||
}
|
||||
|
||||
func (msg *TcActionMsg) Len() int {
|
||||
return SizeofTcActionMsg
|
||||
}
|
||||
|
||||
func DeserializeTcActionMsg(b []byte) *TcActionMsg {
|
||||
return (*TcActionMsg)(unsafe.Pointer(&b[0:SizeofTcActionMsg][0]))
|
||||
}
|
||||
|
||||
func (x *TcActionMsg) Serialize() []byte {
|
||||
return (*(*[SizeofTcActionMsg]byte)(unsafe.Pointer(x)))[:]
|
||||
}
|
||||
|
||||
const (
|
||||
TC_PRIO_MAX = 15
|
||||
)
|
||||
|
||||
// struct tc_prio_qopt {
|
||||
// int bands; /* Number of bands */
|
||||
// __u8 priomap[TC_PRIO_MAX+1]; /* Map: logical priority -> PRIO band */
|
||||
// };
|
||||
|
||||
type TcPrioMap struct {
|
||||
Bands int32
|
||||
Priomap [TC_PRIO_MAX + 1]uint8
|
||||
}
|
||||
|
||||
func (msg *TcPrioMap) Len() int {
|
||||
return SizeofTcPrioMap
|
||||
}
|
||||
|
||||
func DeserializeTcPrioMap(b []byte) *TcPrioMap {
|
||||
return (*TcPrioMap)(unsafe.Pointer(&b[0:SizeofTcPrioMap][0]))
|
||||
}
|
||||
|
||||
func (x *TcPrioMap) Serialize() []byte {
|
||||
return (*(*[SizeofTcPrioMap]byte)(unsafe.Pointer(x)))[:]
|
||||
}
|
||||
|
||||
const (
|
||||
TCA_TBF_UNSPEC = iota
|
||||
TCA_TBF_PARMS
|
||||
TCA_TBF_RTAB
|
||||
TCA_TBF_PTAB
|
||||
TCA_TBF_RATE64
|
||||
TCA_TBF_PRATE64
|
||||
TCA_TBF_BURST
|
||||
TCA_TBF_PBURST
|
||||
TCA_TBF_MAX = TCA_TBF_PBURST
|
||||
)
|
||||
|
||||
// struct tc_ratespec {
|
||||
// unsigned char cell_log;
|
||||
// __u8 linklayer; /* lower 4 bits */
|
||||
// unsigned short overhead;
|
||||
// short cell_align;
|
||||
// unsigned short mpu;
|
||||
// __u32 rate;
|
||||
// };
|
||||
|
||||
type TcRateSpec struct {
|
||||
CellLog uint8
|
||||
Linklayer uint8
|
||||
Overhead uint16
|
||||
CellAlign int16
|
||||
Mpu uint16
|
||||
Rate uint32
|
||||
}
|
||||
|
||||
func (msg *TcRateSpec) Len() int {
|
||||
return SizeofTcRateSpec
|
||||
}
|
||||
|
||||
func DeserializeTcRateSpec(b []byte) *TcRateSpec {
|
||||
return (*TcRateSpec)(unsafe.Pointer(&b[0:SizeofTcRateSpec][0]))
|
||||
}
|
||||
|
||||
func (x *TcRateSpec) Serialize() []byte {
|
||||
return (*(*[SizeofTcRateSpec]byte)(unsafe.Pointer(x)))[:]
|
||||
}
|
||||
|
||||
// struct tc_tbf_qopt {
|
||||
// struct tc_ratespec rate;
|
||||
// struct tc_ratespec peakrate;
|
||||
// __u32 limit;
|
||||
// __u32 buffer;
|
||||
// __u32 mtu;
|
||||
// };
|
||||
|
||||
type TcTbfQopt struct {
|
||||
Rate TcRateSpec
|
||||
Peakrate TcRateSpec
|
||||
Limit uint32
|
||||
Buffer uint32
|
||||
Mtu uint32
|
||||
}
|
||||
|
||||
func (msg *TcTbfQopt) Len() int {
|
||||
return SizeofTcTbfQopt
|
||||
}
|
||||
|
||||
func DeserializeTcTbfQopt(b []byte) *TcTbfQopt {
|
||||
return (*TcTbfQopt)(unsafe.Pointer(&b[0:SizeofTcTbfQopt][0]))
|
||||
}
|
||||
|
||||
func (x *TcTbfQopt) Serialize() []byte {
|
||||
return (*(*[SizeofTcTbfQopt]byte)(unsafe.Pointer(x)))[:]
|
||||
}
|
||||
|
||||
const (
|
||||
TCA_HTB_UNSPEC = iota
|
||||
TCA_HTB_PARMS
|
||||
TCA_HTB_INIT
|
||||
TCA_HTB_CTAB
|
||||
TCA_HTB_RTAB
|
||||
TCA_HTB_DIRECT_QLEN
|
||||
TCA_HTB_RATE64
|
||||
TCA_HTB_CEIL64
|
||||
TCA_HTB_MAX = TCA_HTB_CEIL64
|
||||
)
|
||||
|
||||
//struct tc_htb_opt {
|
||||
// struct tc_ratespec rate;
|
||||
// struct tc_ratespec ceil;
|
||||
// __u32 buffer;
|
||||
// __u32 cbuffer;
|
||||
// __u32 quantum;
|
||||
// __u32 level; /* out only */
|
||||
// __u32 prio;
|
||||
//};
|
||||
|
||||
type TcHtbCopt struct {
|
||||
Rate TcRateSpec
|
||||
Ceil TcRateSpec
|
||||
Buffer uint32
|
||||
Cbuffer uint32
|
||||
Quantum uint32
|
||||
Level uint32
|
||||
Prio uint32
|
||||
}
|
||||
|
||||
func (msg *TcHtbCopt) Len() int {
|
||||
return SizeofTcHtbCopt
|
||||
}
|
||||
|
||||
func DeserializeTcHtbCopt(b []byte) *TcHtbCopt {
|
||||
return (*TcHtbCopt)(unsafe.Pointer(&b[0:SizeofTcHtbCopt][0]))
|
||||
}
|
||||
|
||||
func (x *TcHtbCopt) Serialize() []byte {
|
||||
return (*(*[SizeofTcHtbCopt]byte)(unsafe.Pointer(x)))[:]
|
||||
}
|
||||
|
||||
type TcHtbGlob struct {
|
||||
Version uint32
|
||||
Rate2Quantum uint32
|
||||
Defcls uint32
|
||||
Debug uint32
|
||||
DirectPkts uint32
|
||||
}
|
||||
|
||||
func (msg *TcHtbGlob) Len() int {
|
||||
return SizeofTcHtbGlob
|
||||
}
|
||||
|
||||
func DeserializeTcHtbGlob(b []byte) *TcHtbGlob {
|
||||
return (*TcHtbGlob)(unsafe.Pointer(&b[0:SizeofTcHtbGlob][0]))
|
||||
}
|
||||
|
||||
func (x *TcHtbGlob) Serialize() []byte {
|
||||
return (*(*[SizeofTcHtbGlob]byte)(unsafe.Pointer(x)))[:]
|
||||
}
|
||||
|
||||
const (
|
||||
TCA_U32_UNSPEC = iota
|
||||
TCA_U32_CLASSID
|
||||
TCA_U32_HASH
|
||||
TCA_U32_LINK
|
||||
TCA_U32_DIVISOR
|
||||
TCA_U32_SEL
|
||||
TCA_U32_POLICE
|
||||
TCA_U32_ACT
|
||||
TCA_U32_INDEV
|
||||
TCA_U32_PCNT
|
||||
TCA_U32_MARK
|
||||
TCA_U32_MAX = TCA_U32_MARK
|
||||
)
|
||||
|
||||
// struct tc_u32_key {
|
||||
// __be32 mask;
|
||||
// __be32 val;
|
||||
// int off;
|
||||
// int offmask;
|
||||
// };
|
||||
|
||||
type TcU32Key struct {
|
||||
Mask uint32 // big endian
|
||||
Val uint32 // big endian
|
||||
Off int32
|
||||
OffMask int32
|
||||
}
|
||||
|
||||
func (msg *TcU32Key) Len() int {
|
||||
return SizeofTcU32Key
|
||||
}
|
||||
|
||||
func DeserializeTcU32Key(b []byte) *TcU32Key {
|
||||
return (*TcU32Key)(unsafe.Pointer(&b[0:SizeofTcU32Key][0]))
|
||||
}
|
||||
|
||||
func (x *TcU32Key) Serialize() []byte {
|
||||
return (*(*[SizeofTcU32Key]byte)(unsafe.Pointer(x)))[:]
|
||||
}
|
||||
|
||||
// struct tc_u32_sel {
|
||||
// unsigned char flags;
|
||||
// unsigned char offshift;
|
||||
// unsigned char nkeys;
|
||||
//
|
||||
// __be16 offmask;
|
||||
// __u16 off;
|
||||
// short offoff;
|
||||
//
|
||||
// short hoff;
|
||||
// __be32 hmask;
|
||||
// struct tc_u32_key keys[0];
|
||||
// };
|
||||
|
||||
const (
|
||||
TC_U32_TERMINAL = 1 << iota
|
||||
TC_U32_OFFSET = 1 << iota
|
||||
TC_U32_VAROFFSET = 1 << iota
|
||||
TC_U32_EAT = 1 << iota
|
||||
)
|
||||
|
||||
type TcU32Sel struct {
|
||||
Flags uint8
|
||||
Offshift uint8
|
||||
Nkeys uint8
|
||||
Pad uint8
|
||||
Offmask uint16 // big endian
|
||||
Off uint16
|
||||
Offoff int16
|
||||
Hoff int16
|
||||
Hmask uint32 // big endian
|
||||
Keys []TcU32Key
|
||||
}
|
||||
|
||||
func (msg *TcU32Sel) Len() int {
|
||||
return SizeofTcU32Sel + int(msg.Nkeys)*SizeofTcU32Key
|
||||
}
|
||||
|
||||
func DeserializeTcU32Sel(b []byte) *TcU32Sel {
|
||||
x := &TcU32Sel{}
|
||||
copy((*(*[SizeofTcU32Sel]byte)(unsafe.Pointer(x)))[:], b)
|
||||
next := SizeofTcU32Sel
|
||||
var i uint8
|
||||
for i = 0; i < x.Nkeys; i++ {
|
||||
x.Keys = append(x.Keys, *DeserializeTcU32Key(b[next:]))
|
||||
next += SizeofTcU32Key
|
||||
}
|
||||
return x
|
||||
}
|
||||
|
||||
func (x *TcU32Sel) Serialize() []byte {
|
||||
// This can't just unsafe.cast because it must iterate through keys.
|
||||
buf := make([]byte, x.Len())
|
||||
copy(buf, (*(*[SizeofTcU32Sel]byte)(unsafe.Pointer(x)))[:])
|
||||
next := SizeofTcU32Sel
|
||||
for _, key := range x.Keys {
|
||||
keyBuf := key.Serialize()
|
||||
copy(buf[next:], keyBuf)
|
||||
next += SizeofTcU32Key
|
||||
}
|
||||
return buf
|
||||
}
|
||||
|
||||
const (
|
||||
TCA_ACT_MIRRED = 8
|
||||
)
|
||||
|
||||
const (
|
||||
TCA_MIRRED_UNSPEC = iota
|
||||
TCA_MIRRED_TM
|
||||
TCA_MIRRED_PARMS
|
||||
TCA_MIRRED_MAX = TCA_MIRRED_PARMS
|
||||
)
|
||||
|
||||
const (
|
||||
TCA_EGRESS_REDIR = 1 /* packet redirect to EGRESS*/
|
||||
TCA_EGRESS_MIRROR = 2 /* mirror packet to EGRESS */
|
||||
TCA_INGRESS_REDIR = 3 /* packet redirect to INGRESS*/
|
||||
TCA_INGRESS_MIRROR = 4 /* mirror packet to INGRESS */
|
||||
)
|
||||
|
||||
const (
|
||||
TC_ACT_UNSPEC = int32(-1)
|
||||
TC_ACT_OK = 0
|
||||
TC_ACT_RECLASSIFY = 1
|
||||
TC_ACT_SHOT = 2
|
||||
TC_ACT_PIPE = 3
|
||||
TC_ACT_STOLEN = 4
|
||||
TC_ACT_QUEUED = 5
|
||||
TC_ACT_REPEAT = 6
|
||||
TC_ACT_JUMP = 0x10000000
|
||||
)
|
||||
|
||||
// #define tc_gen \
|
||||
// __u32 index; \
|
||||
// __u32 capab; \
|
||||
// int action; \
|
||||
// int refcnt; \
|
||||
// int bindcnt
|
||||
// struct tc_mirred {
|
||||
// tc_gen;
|
||||
// int eaction; /* one of IN/EGRESS_MIRROR/REDIR */
|
||||
// __u32 ifindex; /* ifindex of egress port */
|
||||
// };
|
||||
|
||||
type TcMirred struct {
|
||||
Index uint32
|
||||
Capab uint32
|
||||
Action int32
|
||||
Refcnt int32
|
||||
Bindcnt int32
|
||||
Eaction int32
|
||||
Ifindex uint32
|
||||
}
|
||||
|
||||
func (msg *TcMirred) Len() int {
|
||||
return SizeofTcMirred
|
||||
}
|
||||
|
||||
func DeserializeTcMirred(b []byte) *TcMirred {
|
||||
return (*TcMirred)(unsafe.Pointer(&b[0:SizeofTcMirred][0]))
|
||||
}
|
||||
|
||||
func (x *TcMirred) Serialize() []byte {
|
||||
return (*(*[SizeofTcMirred]byte)(unsafe.Pointer(x)))[:]
|
||||
}
|
||||
|
||||
const (
|
||||
TC_POLICE_UNSPEC = TC_ACT_UNSPEC
|
||||
TC_POLICE_OK = TC_ACT_OK
|
||||
TC_POLICE_RECLASSIFY = TC_ACT_RECLASSIFY
|
||||
TC_POLICE_SHOT = TC_ACT_SHOT
|
||||
TC_POLICE_PIPE = TC_ACT_PIPE
|
||||
)
|
||||
|
||||
// struct tc_police {
|
||||
// __u32 index;
|
||||
// int action;
|
||||
// __u32 limit;
|
||||
// __u32 burst;
|
||||
// __u32 mtu;
|
||||
// struct tc_ratespec rate;
|
||||
// struct tc_ratespec peakrate;
|
||||
// int refcnt;
|
||||
// int bindcnt;
|
||||
// __u32 capab;
|
||||
// };
|
||||
|
||||
type TcPolice struct {
|
||||
Index uint32
|
||||
Action int32
|
||||
Limit uint32
|
||||
Burst uint32
|
||||
Mtu uint32
|
||||
Rate TcRateSpec
|
||||
PeakRate TcRateSpec
|
||||
Refcnt int32
|
||||
Bindcnt int32
|
||||
Capab uint32
|
||||
}
|
||||
|
||||
func (msg *TcPolice) Len() int {
|
||||
return SizeofTcPolice
|
||||
}
|
||||
|
||||
func DeserializeTcPolice(b []byte) *TcPolice {
|
||||
return (*TcPolice)(unsafe.Pointer(&b[0:SizeofTcPolice][0]))
|
||||
}
|
||||
|
||||
func (x *TcPolice) Serialize() []byte {
|
||||
return (*(*[SizeofTcPolice]byte)(unsafe.Pointer(x)))[:]
|
||||
}
|
||||
|
||||
const (
|
||||
TCA_FW_UNSPEC = iota
|
||||
TCA_FW_CLASSID
|
||||
TCA_FW_POLICE
|
||||
TCA_FW_INDEV
|
||||
TCA_FW_ACT
|
||||
TCA_FW_MASK
|
||||
TCA_FW_MAX = TCA_FW_MASK
|
||||
)
|
161
libnetwork/Godeps/_workspace/src/github.com/vishvananda/netlink/nl/xfrm_linux_test.go
generated
vendored
161
libnetwork/Godeps/_workspace/src/github.com/vishvananda/netlink/nl/xfrm_linux_test.go
generated
vendored
|
@ -1,161 +0,0 @@
|
|||
package nl
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"crypto/rand"
|
||||
"encoding/binary"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func (msg *XfrmAddress) write(b []byte) {
|
||||
copy(b[0:SizeofXfrmAddress], msg[:])
|
||||
}
|
||||
|
||||
func (msg *XfrmAddress) serializeSafe() []byte {
|
||||
b := make([]byte, SizeofXfrmAddress)
|
||||
msg.write(b)
|
||||
return b
|
||||
}
|
||||
|
||||
func deserializeXfrmAddressSafe(b []byte) *XfrmAddress {
|
||||
var msg = XfrmAddress{}
|
||||
binary.Read(bytes.NewReader(b[0:SizeofXfrmAddress]), NativeEndian(), &msg)
|
||||
return &msg
|
||||
}
|
||||
|
||||
func TestXfrmAddressDeserializeSerialize(t *testing.T) {
|
||||
var orig = make([]byte, SizeofXfrmAddress)
|
||||
rand.Read(orig)
|
||||
safemsg := deserializeXfrmAddressSafe(orig)
|
||||
msg := DeserializeXfrmAddress(orig)
|
||||
testDeserializeSerialize(t, orig, safemsg, msg)
|
||||
}
|
||||
|
||||
func (msg *XfrmSelector) write(b []byte) {
|
||||
const AddrEnd = SizeofXfrmAddress * 2
|
||||
native := NativeEndian()
|
||||
msg.Daddr.write(b[0:SizeofXfrmAddress])
|
||||
msg.Saddr.write(b[SizeofXfrmAddress:AddrEnd])
|
||||
native.PutUint16(b[AddrEnd:AddrEnd+2], msg.Dport)
|
||||
native.PutUint16(b[AddrEnd+2:AddrEnd+4], msg.DportMask)
|
||||
native.PutUint16(b[AddrEnd+4:AddrEnd+6], msg.Sport)
|
||||
native.PutUint16(b[AddrEnd+6:AddrEnd+8], msg.SportMask)
|
||||
native.PutUint16(b[AddrEnd+8:AddrEnd+10], msg.Family)
|
||||
b[AddrEnd+10] = msg.PrefixlenD
|
||||
b[AddrEnd+11] = msg.PrefixlenS
|
||||
b[AddrEnd+12] = msg.Proto
|
||||
copy(b[AddrEnd+13:AddrEnd+16], msg.Pad[:])
|
||||
native.PutUint32(b[AddrEnd+16:AddrEnd+20], uint32(msg.Ifindex))
|
||||
native.PutUint32(b[AddrEnd+20:AddrEnd+24], msg.User)
|
||||
}
|
||||
|
||||
func (msg *XfrmSelector) serializeSafe() []byte {
|
||||
length := SizeofXfrmSelector
|
||||
b := make([]byte, length)
|
||||
msg.write(b)
|
||||
return b
|
||||
}
|
||||
|
||||
func deserializeXfrmSelectorSafe(b []byte) *XfrmSelector {
|
||||
var msg = XfrmSelector{}
|
||||
binary.Read(bytes.NewReader(b[0:SizeofXfrmSelector]), NativeEndian(), &msg)
|
||||
return &msg
|
||||
}
|
||||
|
||||
func TestXfrmSelectorDeserializeSerialize(t *testing.T) {
|
||||
var orig = make([]byte, SizeofXfrmSelector)
|
||||
rand.Read(orig)
|
||||
safemsg := deserializeXfrmSelectorSafe(orig)
|
||||
msg := DeserializeXfrmSelector(orig)
|
||||
testDeserializeSerialize(t, orig, safemsg, msg)
|
||||
}
|
||||
|
||||
func (msg *XfrmLifetimeCfg) write(b []byte) {
|
||||
native := NativeEndian()
|
||||
native.PutUint64(b[0:8], msg.SoftByteLimit)
|
||||
native.PutUint64(b[8:16], msg.HardByteLimit)
|
||||
native.PutUint64(b[16:24], msg.SoftPacketLimit)
|
||||
native.PutUint64(b[24:32], msg.HardPacketLimit)
|
||||
native.PutUint64(b[32:40], msg.SoftAddExpiresSeconds)
|
||||
native.PutUint64(b[40:48], msg.HardAddExpiresSeconds)
|
||||
native.PutUint64(b[48:56], msg.SoftUseExpiresSeconds)
|
||||
native.PutUint64(b[56:64], msg.HardUseExpiresSeconds)
|
||||
}
|
||||
|
||||
func (msg *XfrmLifetimeCfg) serializeSafe() []byte {
|
||||
length := SizeofXfrmLifetimeCfg
|
||||
b := make([]byte, length)
|
||||
msg.write(b)
|
||||
return b
|
||||
}
|
||||
|
||||
func deserializeXfrmLifetimeCfgSafe(b []byte) *XfrmLifetimeCfg {
|
||||
var msg = XfrmLifetimeCfg{}
|
||||
binary.Read(bytes.NewReader(b[0:SizeofXfrmLifetimeCfg]), NativeEndian(), &msg)
|
||||
return &msg
|
||||
}
|
||||
|
||||
func TestXfrmLifetimeCfgDeserializeSerialize(t *testing.T) {
|
||||
var orig = make([]byte, SizeofXfrmLifetimeCfg)
|
||||
rand.Read(orig)
|
||||
safemsg := deserializeXfrmLifetimeCfgSafe(orig)
|
||||
msg := DeserializeXfrmLifetimeCfg(orig)
|
||||
testDeserializeSerialize(t, orig, safemsg, msg)
|
||||
}
|
||||
|
||||
func (msg *XfrmLifetimeCur) write(b []byte) {
|
||||
native := NativeEndian()
|
||||
native.PutUint64(b[0:8], msg.Bytes)
|
||||
native.PutUint64(b[8:16], msg.Packets)
|
||||
native.PutUint64(b[16:24], msg.AddTime)
|
||||
native.PutUint64(b[24:32], msg.UseTime)
|
||||
}
|
||||
|
||||
func (msg *XfrmLifetimeCur) serializeSafe() []byte {
|
||||
length := SizeofXfrmLifetimeCur
|
||||
b := make([]byte, length)
|
||||
msg.write(b)
|
||||
return b
|
||||
}
|
||||
|
||||
func deserializeXfrmLifetimeCurSafe(b []byte) *XfrmLifetimeCur {
|
||||
var msg = XfrmLifetimeCur{}
|
||||
binary.Read(bytes.NewReader(b[0:SizeofXfrmLifetimeCur]), NativeEndian(), &msg)
|
||||
return &msg
|
||||
}
|
||||
|
||||
func TestXfrmLifetimeCurDeserializeSerialize(t *testing.T) {
|
||||
var orig = make([]byte, SizeofXfrmLifetimeCur)
|
||||
rand.Read(orig)
|
||||
safemsg := deserializeXfrmLifetimeCurSafe(orig)
|
||||
msg := DeserializeXfrmLifetimeCur(orig)
|
||||
testDeserializeSerialize(t, orig, safemsg, msg)
|
||||
}
|
||||
|
||||
func (msg *XfrmId) write(b []byte) {
|
||||
native := NativeEndian()
|
||||
msg.Daddr.write(b[0:SizeofXfrmAddress])
|
||||
native.PutUint32(b[SizeofXfrmAddress:SizeofXfrmAddress+4], msg.Spi)
|
||||
b[SizeofXfrmAddress+4] = msg.Proto
|
||||
copy(b[SizeofXfrmAddress+5:SizeofXfrmAddress+8], msg.Pad[:])
|
||||
}
|
||||
|
||||
func (msg *XfrmId) serializeSafe() []byte {
|
||||
b := make([]byte, SizeofXfrmId)
|
||||
msg.write(b)
|
||||
return b
|
||||
}
|
||||
|
||||
func deserializeXfrmIdSafe(b []byte) *XfrmId {
|
||||
var msg = XfrmId{}
|
||||
binary.Read(bytes.NewReader(b[0:SizeofXfrmId]), NativeEndian(), &msg)
|
||||
return &msg
|
||||
}
|
||||
|
||||
func TestXfrmIdDeserializeSerialize(t *testing.T) {
|
||||
var orig = make([]byte, SizeofXfrmId)
|
||||
rand.Read(orig)
|
||||
safemsg := deserializeXfrmIdSafe(orig)
|
||||
msg := DeserializeXfrmId(orig)
|
||||
testDeserializeSerialize(t, orig, safemsg, msg)
|
||||
}
|
109
libnetwork/Godeps/_workspace/src/github.com/vishvananda/netlink/nl/xfrm_policy_linux_test.go
generated
vendored
109
libnetwork/Godeps/_workspace/src/github.com/vishvananda/netlink/nl/xfrm_policy_linux_test.go
generated
vendored
|
@ -1,109 +0,0 @@
|
|||
package nl
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"crypto/rand"
|
||||
"encoding/binary"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func (msg *XfrmUserpolicyId) write(b []byte) {
|
||||
native := NativeEndian()
|
||||
msg.Sel.write(b[0:SizeofXfrmSelector])
|
||||
native.PutUint32(b[SizeofXfrmSelector:SizeofXfrmSelector+4], msg.Index)
|
||||
b[SizeofXfrmSelector+4] = msg.Dir
|
||||
copy(b[SizeofXfrmSelector+5:SizeofXfrmSelector+8], msg.Pad[:])
|
||||
}
|
||||
|
||||
func (msg *XfrmUserpolicyId) serializeSafe() []byte {
|
||||
b := make([]byte, SizeofXfrmUserpolicyId)
|
||||
msg.write(b)
|
||||
return b
|
||||
}
|
||||
|
||||
func deserializeXfrmUserpolicyIdSafe(b []byte) *XfrmUserpolicyId {
|
||||
var msg = XfrmUserpolicyId{}
|
||||
binary.Read(bytes.NewReader(b[0:SizeofXfrmUserpolicyId]), NativeEndian(), &msg)
|
||||
return &msg
|
||||
}
|
||||
|
||||
func TestXfrmUserpolicyIdDeserializeSerialize(t *testing.T) {
|
||||
var orig = make([]byte, SizeofXfrmUserpolicyId)
|
||||
rand.Read(orig)
|
||||
safemsg := deserializeXfrmUserpolicyIdSafe(orig)
|
||||
msg := DeserializeXfrmUserpolicyId(orig)
|
||||
testDeserializeSerialize(t, orig, safemsg, msg)
|
||||
}
|
||||
|
||||
func (msg *XfrmUserpolicyInfo) write(b []byte) {
|
||||
const CfgEnd = SizeofXfrmSelector + SizeofXfrmLifetimeCfg
|
||||
const CurEnd = CfgEnd + SizeofXfrmLifetimeCur
|
||||
native := NativeEndian()
|
||||
msg.Sel.write(b[0:SizeofXfrmSelector])
|
||||
msg.Lft.write(b[SizeofXfrmSelector:CfgEnd])
|
||||
msg.Curlft.write(b[CfgEnd:CurEnd])
|
||||
native.PutUint32(b[CurEnd:CurEnd+4], msg.Priority)
|
||||
native.PutUint32(b[CurEnd+4:CurEnd+8], msg.Index)
|
||||
b[CurEnd+8] = msg.Dir
|
||||
b[CurEnd+9] = msg.Action
|
||||
b[CurEnd+10] = msg.Flags
|
||||
b[CurEnd+11] = msg.Share
|
||||
copy(b[CurEnd+12:CurEnd+16], msg.Pad[:])
|
||||
}
|
||||
|
||||
func (msg *XfrmUserpolicyInfo) serializeSafe() []byte {
|
||||
b := make([]byte, SizeofXfrmUserpolicyInfo)
|
||||
msg.write(b)
|
||||
return b
|
||||
}
|
||||
|
||||
func deserializeXfrmUserpolicyInfoSafe(b []byte) *XfrmUserpolicyInfo {
|
||||
var msg = XfrmUserpolicyInfo{}
|
||||
binary.Read(bytes.NewReader(b[0:SizeofXfrmUserpolicyInfo]), NativeEndian(), &msg)
|
||||
return &msg
|
||||
}
|
||||
|
||||
func TestXfrmUserpolicyInfoDeserializeSerialize(t *testing.T) {
|
||||
var orig = make([]byte, SizeofXfrmUserpolicyInfo)
|
||||
rand.Read(orig)
|
||||
safemsg := deserializeXfrmUserpolicyInfoSafe(orig)
|
||||
msg := DeserializeXfrmUserpolicyInfo(orig)
|
||||
testDeserializeSerialize(t, orig, safemsg, msg)
|
||||
}
|
||||
|
||||
func (msg *XfrmUserTmpl) write(b []byte) {
|
||||
const AddrEnd = SizeofXfrmId + 4 + SizeofXfrmAddress
|
||||
native := NativeEndian()
|
||||
msg.XfrmId.write(b[0:SizeofXfrmId])
|
||||
native.PutUint16(b[SizeofXfrmId:SizeofXfrmId+2], msg.Family)
|
||||
copy(b[SizeofXfrmId+2:SizeofXfrmId+4], msg.Pad1[:])
|
||||
msg.Saddr.write(b[SizeofXfrmId+4 : AddrEnd])
|
||||
native.PutUint32(b[AddrEnd:AddrEnd+4], msg.Reqid)
|
||||
b[AddrEnd+4] = msg.Mode
|
||||
b[AddrEnd+5] = msg.Share
|
||||
b[AddrEnd+6] = msg.Optional
|
||||
b[AddrEnd+7] = msg.Pad2
|
||||
native.PutUint32(b[AddrEnd+8:AddrEnd+12], msg.Aalgos)
|
||||
native.PutUint32(b[AddrEnd+12:AddrEnd+16], msg.Ealgos)
|
||||
native.PutUint32(b[AddrEnd+16:AddrEnd+20], msg.Calgos)
|
||||
}
|
||||
|
||||
func (msg *XfrmUserTmpl) serializeSafe() []byte {
|
||||
b := make([]byte, SizeofXfrmUserTmpl)
|
||||
msg.write(b)
|
||||
return b
|
||||
}
|
||||
|
||||
func deserializeXfrmUserTmplSafe(b []byte) *XfrmUserTmpl {
|
||||
var msg = XfrmUserTmpl{}
|
||||
binary.Read(bytes.NewReader(b[0:SizeofXfrmUserTmpl]), NativeEndian(), &msg)
|
||||
return &msg
|
||||
}
|
||||
|
||||
func TestXfrmUserTmplDeserializeSerialize(t *testing.T) {
|
||||
var orig = make([]byte, SizeofXfrmUserTmpl)
|
||||
rand.Read(orig)
|
||||
safemsg := deserializeXfrmUserTmplSafe(orig)
|
||||
msg := DeserializeXfrmUserTmpl(orig)
|
||||
testDeserializeSerialize(t, orig, safemsg, msg)
|
||||
}
|
207
libnetwork/Godeps/_workspace/src/github.com/vishvananda/netlink/nl/xfrm_state_linux_test.go
generated
vendored
207
libnetwork/Godeps/_workspace/src/github.com/vishvananda/netlink/nl/xfrm_state_linux_test.go
generated
vendored
|
@ -1,207 +0,0 @@
|
|||
package nl
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"crypto/rand"
|
||||
"encoding/binary"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func (msg *XfrmUsersaId) write(b []byte) {
|
||||
native := NativeEndian()
|
||||
msg.Daddr.write(b[0:SizeofXfrmAddress])
|
||||
native.PutUint32(b[SizeofXfrmAddress:SizeofXfrmAddress+4], msg.Spi)
|
||||
native.PutUint16(b[SizeofXfrmAddress+4:SizeofXfrmAddress+6], msg.Family)
|
||||
b[SizeofXfrmAddress+6] = msg.Proto
|
||||
b[SizeofXfrmAddress+7] = msg.Pad
|
||||
}
|
||||
|
||||
func (msg *XfrmUsersaId) serializeSafe() []byte {
|
||||
b := make([]byte, SizeofXfrmUsersaId)
|
||||
msg.write(b)
|
||||
return b
|
||||
}
|
||||
|
||||
func deserializeXfrmUsersaIdSafe(b []byte) *XfrmUsersaId {
|
||||
var msg = XfrmUsersaId{}
|
||||
binary.Read(bytes.NewReader(b[0:SizeofXfrmUsersaId]), NativeEndian(), &msg)
|
||||
return &msg
|
||||
}
|
||||
|
||||
func TestXfrmUsersaIdDeserializeSerialize(t *testing.T) {
|
||||
var orig = make([]byte, SizeofXfrmUsersaId)
|
||||
rand.Read(orig)
|
||||
safemsg := deserializeXfrmUsersaIdSafe(orig)
|
||||
msg := DeserializeXfrmUsersaId(orig)
|
||||
testDeserializeSerialize(t, orig, safemsg, msg)
|
||||
}
|
||||
|
||||
func (msg *XfrmStats) write(b []byte) {
|
||||
native := NativeEndian()
|
||||
native.PutUint32(b[0:4], msg.ReplayWindow)
|
||||
native.PutUint32(b[4:8], msg.Replay)
|
||||
native.PutUint32(b[8:12], msg.IntegrityFailed)
|
||||
}
|
||||
|
||||
func (msg *XfrmStats) serializeSafe() []byte {
|
||||
b := make([]byte, SizeofXfrmStats)
|
||||
msg.write(b)
|
||||
return b
|
||||
}
|
||||
|
||||
func deserializeXfrmStatsSafe(b []byte) *XfrmStats {
|
||||
var msg = XfrmStats{}
|
||||
binary.Read(bytes.NewReader(b[0:SizeofXfrmStats]), NativeEndian(), &msg)
|
||||
return &msg
|
||||
}
|
||||
|
||||
func TestXfrmStatsDeserializeSerialize(t *testing.T) {
|
||||
var orig = make([]byte, SizeofXfrmStats)
|
||||
rand.Read(orig)
|
||||
safemsg := deserializeXfrmStatsSafe(orig)
|
||||
msg := DeserializeXfrmStats(orig)
|
||||
testDeserializeSerialize(t, orig, safemsg, msg)
|
||||
}
|
||||
|
||||
func (msg *XfrmUsersaInfo) write(b []byte) {
|
||||
const IdEnd = SizeofXfrmSelector + SizeofXfrmId
|
||||
const AddressEnd = IdEnd + SizeofXfrmAddress
|
||||
const CfgEnd = AddressEnd + SizeofXfrmLifetimeCfg
|
||||
const CurEnd = CfgEnd + SizeofXfrmLifetimeCur
|
||||
const StatsEnd = CurEnd + SizeofXfrmStats
|
||||
native := NativeEndian()
|
||||
msg.Sel.write(b[0:SizeofXfrmSelector])
|
||||
msg.Id.write(b[SizeofXfrmSelector:IdEnd])
|
||||
msg.Saddr.write(b[IdEnd:AddressEnd])
|
||||
msg.Lft.write(b[AddressEnd:CfgEnd])
|
||||
msg.Curlft.write(b[CfgEnd:CurEnd])
|
||||
msg.Stats.write(b[CurEnd:StatsEnd])
|
||||
native.PutUint32(b[StatsEnd:StatsEnd+4], msg.Seq)
|
||||
native.PutUint32(b[StatsEnd+4:StatsEnd+8], msg.Reqid)
|
||||
native.PutUint16(b[StatsEnd+8:StatsEnd+10], msg.Family)
|
||||
b[StatsEnd+10] = msg.Mode
|
||||
b[StatsEnd+11] = msg.ReplayWindow
|
||||
b[StatsEnd+12] = msg.Flags
|
||||
copy(b[StatsEnd+13:StatsEnd+20], msg.Pad[:])
|
||||
}
|
||||
|
||||
func (msg *XfrmUsersaInfo) serializeSafe() []byte {
|
||||
b := make([]byte, SizeofXfrmUsersaInfo)
|
||||
msg.write(b)
|
||||
return b
|
||||
}
|
||||
|
||||
func deserializeXfrmUsersaInfoSafe(b []byte) *XfrmUsersaInfo {
|
||||
var msg = XfrmUsersaInfo{}
|
||||
binary.Read(bytes.NewReader(b[0:SizeofXfrmUsersaInfo]), NativeEndian(), &msg)
|
||||
return &msg
|
||||
}
|
||||
|
||||
func TestXfrmUsersaInfoDeserializeSerialize(t *testing.T) {
|
||||
var orig = make([]byte, SizeofXfrmUsersaInfo)
|
||||
rand.Read(orig)
|
||||
safemsg := deserializeXfrmUsersaInfoSafe(orig)
|
||||
msg := DeserializeXfrmUsersaInfo(orig)
|
||||
testDeserializeSerialize(t, orig, safemsg, msg)
|
||||
}
|
||||
|
||||
func (msg *XfrmAlgo) write(b []byte) {
|
||||
native := NativeEndian()
|
||||
copy(b[0:64], msg.AlgName[:])
|
||||
native.PutUint32(b[64:68], msg.AlgKeyLen)
|
||||
copy(b[68:msg.Len()], msg.AlgKey[:])
|
||||
}
|
||||
|
||||
func (msg *XfrmAlgo) serializeSafe() []byte {
|
||||
b := make([]byte, msg.Len())
|
||||
msg.write(b)
|
||||
return b
|
||||
}
|
||||
|
||||
func deserializeXfrmAlgoSafe(b []byte) *XfrmAlgo {
|
||||
var msg = XfrmAlgo{}
|
||||
copy(msg.AlgName[:], b[0:64])
|
||||
binary.Read(bytes.NewReader(b[64:68]), NativeEndian(), &msg.AlgKeyLen)
|
||||
msg.AlgKey = b[68:msg.Len()]
|
||||
return &msg
|
||||
}
|
||||
|
||||
func TestXfrmAlgoDeserializeSerialize(t *testing.T) {
|
||||
// use a 32 byte key len
|
||||
var orig = make([]byte, SizeofXfrmAlgo+32)
|
||||
rand.Read(orig)
|
||||
// set the key len to 256 bits
|
||||
orig[64] = 0
|
||||
orig[65] = 1
|
||||
orig[66] = 0
|
||||
orig[67] = 0
|
||||
safemsg := deserializeXfrmAlgoSafe(orig)
|
||||
msg := DeserializeXfrmAlgo(orig)
|
||||
testDeserializeSerialize(t, orig, safemsg, msg)
|
||||
}
|
||||
|
||||
func (msg *XfrmAlgoAuth) write(b []byte) {
|
||||
native := NativeEndian()
|
||||
copy(b[0:64], msg.AlgName[:])
|
||||
native.PutUint32(b[64:68], msg.AlgKeyLen)
|
||||
native.PutUint32(b[68:72], msg.AlgTruncLen)
|
||||
copy(b[72:msg.Len()], msg.AlgKey[:])
|
||||
}
|
||||
|
||||
func (msg *XfrmAlgoAuth) serializeSafe() []byte {
|
||||
b := make([]byte, msg.Len())
|
||||
msg.write(b)
|
||||
return b
|
||||
}
|
||||
|
||||
func deserializeXfrmAlgoAuthSafe(b []byte) *XfrmAlgoAuth {
|
||||
var msg = XfrmAlgoAuth{}
|
||||
copy(msg.AlgName[:], b[0:64])
|
||||
binary.Read(bytes.NewReader(b[64:68]), NativeEndian(), &msg.AlgKeyLen)
|
||||
binary.Read(bytes.NewReader(b[68:72]), NativeEndian(), &msg.AlgTruncLen)
|
||||
msg.AlgKey = b[72:msg.Len()]
|
||||
return &msg
|
||||
}
|
||||
|
||||
func TestXfrmAlgoAuthDeserializeSerialize(t *testing.T) {
|
||||
// use a 32 byte key len
|
||||
var orig = make([]byte, SizeofXfrmAlgoAuth+32)
|
||||
rand.Read(orig)
|
||||
// set the key len to 256 bits
|
||||
orig[64] = 0
|
||||
orig[65] = 1
|
||||
orig[66] = 0
|
||||
orig[67] = 0
|
||||
safemsg := deserializeXfrmAlgoAuthSafe(orig)
|
||||
msg := DeserializeXfrmAlgoAuth(orig)
|
||||
testDeserializeSerialize(t, orig, safemsg, msg)
|
||||
}
|
||||
|
||||
func (msg *XfrmEncapTmpl) write(b []byte) {
|
||||
native := NativeEndian()
|
||||
native.PutUint16(b[0:2], msg.EncapType)
|
||||
native.PutUint16(b[2:4], msg.EncapSport)
|
||||
native.PutUint16(b[4:6], msg.EncapDport)
|
||||
copy(b[6:8], msg.Pad[:])
|
||||
msg.EncapOa.write(b[8:SizeofXfrmAddress])
|
||||
}
|
||||
|
||||
func (msg *XfrmEncapTmpl) serializeSafe() []byte {
|
||||
b := make([]byte, SizeofXfrmEncapTmpl)
|
||||
msg.write(b)
|
||||
return b
|
||||
}
|
||||
|
||||
func deserializeXfrmEncapTmplSafe(b []byte) *XfrmEncapTmpl {
|
||||
var msg = XfrmEncapTmpl{}
|
||||
binary.Read(bytes.NewReader(b[0:SizeofXfrmEncapTmpl]), NativeEndian(), &msg)
|
||||
return &msg
|
||||
}
|
||||
|
||||
func TestXfrmEncapTmplDeserializeSerialize(t *testing.T) {
|
||||
var orig = make([]byte, SizeofXfrmEncapTmpl)
|
||||
rand.Read(orig)
|
||||
safemsg := deserializeXfrmEncapTmplSafe(orig)
|
||||
msg := DeserializeXfrmEncapTmpl(orig)
|
||||
testDeserializeSerialize(t, orig, safemsg, msg)
|
||||
}
|
98
libnetwork/Godeps/_workspace/src/github.com/vishvananda/netlink/protinfo_test.go
generated
vendored
98
libnetwork/Godeps/_workspace/src/github.com/vishvananda/netlink/protinfo_test.go
generated
vendored
|
@ -1,98 +0,0 @@
|
|||
package netlink
|
||||
|
||||
import "testing"
|
||||
|
||||
func TestProtinfo(t *testing.T) {
|
||||
tearDown := setUpNetlinkTest(t)
|
||||
defer tearDown()
|
||||
master := &Bridge{LinkAttrs{Name: "foo"}}
|
||||
if err := LinkAdd(master); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
iface1 := &Dummy{LinkAttrs{Name: "bar1", MasterIndex: master.Index}}
|
||||
iface2 := &Dummy{LinkAttrs{Name: "bar2", MasterIndex: master.Index}}
|
||||
iface3 := &Dummy{LinkAttrs{Name: "bar3"}}
|
||||
|
||||
if err := LinkAdd(iface1); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if err := LinkAdd(iface2); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if err := LinkAdd(iface3); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
oldpi1, err := LinkGetProtinfo(iface1)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
oldpi2, err := LinkGetProtinfo(iface2)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if err := LinkSetHairpin(iface1, true); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if err := LinkSetRootBlock(iface1, true); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
pi1, err := LinkGetProtinfo(iface1)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if !pi1.Hairpin {
|
||||
t.Fatalf("Hairpin mode is not enabled for %s, but should", iface1.Name)
|
||||
}
|
||||
if !pi1.RootBlock {
|
||||
t.Fatalf("RootBlock is not enabled for %s, but should", iface1.Name)
|
||||
}
|
||||
if pi1.Guard != oldpi1.Guard {
|
||||
t.Fatalf("Guard field was changed for %s but shouldn't", iface1.Name)
|
||||
}
|
||||
if pi1.FastLeave != oldpi1.FastLeave {
|
||||
t.Fatalf("FastLeave field was changed for %s but shouldn't", iface1.Name)
|
||||
}
|
||||
if pi1.Learning != oldpi1.Learning {
|
||||
t.Fatalf("Learning field was changed for %s but shouldn't", iface1.Name)
|
||||
}
|
||||
if pi1.Flood != oldpi1.Flood {
|
||||
t.Fatalf("Flood field was changed for %s but shouldn't", iface1.Name)
|
||||
}
|
||||
|
||||
if err := LinkSetGuard(iface2, true); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if err := LinkSetLearning(iface2, false); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
pi2, err := LinkGetProtinfo(iface2)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if pi2.Hairpin {
|
||||
t.Fatalf("Hairpin mode is enabled for %s, but shouldn't", iface2.Name)
|
||||
}
|
||||
if !pi2.Guard {
|
||||
t.Fatalf("Guard is not enabled for %s, but should", iface2.Name)
|
||||
}
|
||||
if pi2.Learning {
|
||||
t.Fatalf("Learning is enabled for %s, but shouldn't", iface2.Name)
|
||||
}
|
||||
if pi2.RootBlock != oldpi2.RootBlock {
|
||||
t.Fatalf("RootBlock field was changed for %s but shouldn't", iface2.Name)
|
||||
}
|
||||
if pi2.FastLeave != oldpi2.FastLeave {
|
||||
t.Fatalf("FastLeave field was changed for %s but shouldn't", iface2.Name)
|
||||
}
|
||||
if pi2.Flood != oldpi2.Flood {
|
||||
t.Fatalf("Flood field was changed for %s but shouldn't", iface2.Name)
|
||||
}
|
||||
|
||||
if err := LinkSetHairpin(iface3, true); err == nil || err.Error() != "operation not supported" {
|
||||
t.Fatalf("Set protinfo attrs for link without master is not supported, but err: %s", err)
|
||||
}
|
||||
}
|
167
libnetwork/Godeps/_workspace/src/github.com/vishvananda/netlink/qdisc.go
generated
vendored
Normal file
167
libnetwork/Godeps/_workspace/src/github.com/vishvananda/netlink/qdisc.go
generated
vendored
Normal file
|
@ -0,0 +1,167 @@
|
|||
package netlink
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
)
|
||||
|
||||
const (
|
||||
HANDLE_NONE = 0
|
||||
HANDLE_INGRESS = 0xFFFFFFF1
|
||||
HANDLE_ROOT = 0xFFFFFFFF
|
||||
PRIORITY_MAP_LEN = 16
|
||||
)
|
||||
|
||||
type Qdisc interface {
|
||||
Attrs() *QdiscAttrs
|
||||
Type() string
|
||||
}
|
||||
|
||||
// Qdisc represents a netlink qdisc. A qdisc is associated with a link,
|
||||
// has a handle, a parent and a refcnt. The root qdisc of a device should
|
||||
// have parent == HANDLE_ROOT.
|
||||
type QdiscAttrs struct {
|
||||
LinkIndex int
|
||||
Handle uint32
|
||||
Parent uint32
|
||||
Refcnt uint32 // read only
|
||||
}
|
||||
|
||||
func (q QdiscAttrs) String() string {
|
||||
return fmt.Sprintf("{LinkIndex: %d, Handle: %s, Parent: %s, Refcnt: %s}", q.LinkIndex, HandleStr(q.Handle), HandleStr(q.Parent), q.Refcnt)
|
||||
}
|
||||
|
||||
func MakeHandle(major, minor uint16) uint32 {
|
||||
return (uint32(major) << 16) | uint32(minor)
|
||||
}
|
||||
|
||||
func MajorMinor(handle uint32) (uint16, uint16) {
|
||||
return uint16((handle & 0xFFFF0000) >> 16), uint16(handle & 0x0000FFFFF)
|
||||
}
|
||||
|
||||
func HandleStr(handle uint32) string {
|
||||
switch handle {
|
||||
case HANDLE_NONE:
|
||||
return "none"
|
||||
case HANDLE_INGRESS:
|
||||
return "ingress"
|
||||
case HANDLE_ROOT:
|
||||
return "root"
|
||||
default:
|
||||
major, minor := MajorMinor(handle)
|
||||
return fmt.Sprintf("%x:%x", major, minor)
|
||||
}
|
||||
}
|
||||
|
||||
// PfifoFast is the default qdisc created by the kernel if one has not
|
||||
// been defined for the interface
|
||||
type PfifoFast struct {
|
||||
QdiscAttrs
|
||||
Bands uint8
|
||||
PriorityMap [PRIORITY_MAP_LEN]uint8
|
||||
}
|
||||
|
||||
func (qdisc *PfifoFast) Attrs() *QdiscAttrs {
|
||||
return &qdisc.QdiscAttrs
|
||||
}
|
||||
|
||||
func (qdisc *PfifoFast) Type() string {
|
||||
return "pfifo_fast"
|
||||
}
|
||||
|
||||
// Prio is a basic qdisc that works just like PfifoFast
|
||||
type Prio struct {
|
||||
QdiscAttrs
|
||||
Bands uint8
|
||||
PriorityMap [PRIORITY_MAP_LEN]uint8
|
||||
}
|
||||
|
||||
func NewPrio(attrs QdiscAttrs) *Prio {
|
||||
return &Prio{
|
||||
QdiscAttrs: attrs,
|
||||
Bands: 3,
|
||||
PriorityMap: [PRIORITY_MAP_LEN]uint8{1, 2, 2, 2, 1, 2, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1},
|
||||
}
|
||||
}
|
||||
|
||||
func (qdisc *Prio) Attrs() *QdiscAttrs {
|
||||
return &qdisc.QdiscAttrs
|
||||
}
|
||||
|
||||
func (qdisc *Prio) Type() string {
|
||||
return "prio"
|
||||
}
|
||||
|
||||
// Htb is a classful qdisc that rate limits based on tokens
|
||||
type Htb struct {
|
||||
QdiscAttrs
|
||||
Version uint32
|
||||
Rate2Quantum uint32
|
||||
Defcls uint32
|
||||
Debug uint32
|
||||
DirectPkts uint32
|
||||
}
|
||||
|
||||
func NewHtb(attrs QdiscAttrs) *Htb {
|
||||
return &Htb{
|
||||
QdiscAttrs: attrs,
|
||||
Version: 3,
|
||||
Defcls: 0,
|
||||
Rate2Quantum: 10,
|
||||
Debug: 0,
|
||||
DirectPkts: 0,
|
||||
}
|
||||
}
|
||||
|
||||
func (qdisc *Htb) Attrs() *QdiscAttrs {
|
||||
return &qdisc.QdiscAttrs
|
||||
}
|
||||
|
||||
func (qdisc *Htb) Type() string {
|
||||
return "htb"
|
||||
}
|
||||
|
||||
// Tbf is a classless qdisc that rate limits based on tokens
|
||||
type Tbf struct {
|
||||
QdiscAttrs
|
||||
// TODO: handle 64bit rate properly
|
||||
Rate uint64
|
||||
Limit uint32
|
||||
Buffer uint32
|
||||
// TODO: handle other settings
|
||||
}
|
||||
|
||||
func (qdisc *Tbf) Attrs() *QdiscAttrs {
|
||||
return &qdisc.QdiscAttrs
|
||||
}
|
||||
|
||||
func (qdisc *Tbf) Type() string {
|
||||
return "tbf"
|
||||
}
|
||||
|
||||
// Ingress is a qdisc for adding ingress filters
|
||||
type Ingress struct {
|
||||
QdiscAttrs
|
||||
}
|
||||
|
||||
func (qdisc *Ingress) Attrs() *QdiscAttrs {
|
||||
return &qdisc.QdiscAttrs
|
||||
}
|
||||
|
||||
func (qdisc *Ingress) Type() string {
|
||||
return "ingress"
|
||||
}
|
||||
|
||||
// GenericQdisc qdiscs represent types that are not currently understood
|
||||
// by this netlink library.
|
||||
type GenericQdisc struct {
|
||||
QdiscAttrs
|
||||
QdiscType string
|
||||
}
|
||||
|
||||
func (qdisc *GenericQdisc) Attrs() *QdiscAttrs {
|
||||
return &qdisc.QdiscAttrs
|
||||
}
|
||||
|
||||
func (qdisc *GenericQdisc) Type() string {
|
||||
return qdisc.QdiscType
|
||||
}
|
316
libnetwork/Godeps/_workspace/src/github.com/vishvananda/netlink/qdisc_linux.go
generated
vendored
Normal file
316
libnetwork/Godeps/_workspace/src/github.com/vishvananda/netlink/qdisc_linux.go
generated
vendored
Normal file
|
@ -0,0 +1,316 @@
|
|||
package netlink
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"strconv"
|
||||
"strings"
|
||||
"syscall"
|
||||
|
||||
"github.com/vishvananda/netlink/nl"
|
||||
)
|
||||
|
||||
// QdiscDel will delete a qdisc from the system.
|
||||
// Equivalent to: `tc qdisc del $qdisc`
|
||||
func QdiscDel(qdisc Qdisc) error {
|
||||
req := nl.NewNetlinkRequest(syscall.RTM_DELQDISC, syscall.NLM_F_ACK)
|
||||
base := qdisc.Attrs()
|
||||
msg := &nl.TcMsg{
|
||||
Family: nl.FAMILY_ALL,
|
||||
Ifindex: int32(base.LinkIndex),
|
||||
Handle: base.Handle,
|
||||
Parent: base.Parent,
|
||||
}
|
||||
req.AddData(msg)
|
||||
|
||||
_, err := req.Execute(syscall.NETLINK_ROUTE, 0)
|
||||
return err
|
||||
}
|
||||
|
||||
// QdiscAdd will add a qdisc to the system.
|
||||
// Equivalent to: `tc qdisc add $qdisc`
|
||||
func QdiscAdd(qdisc Qdisc) error {
|
||||
req := nl.NewNetlinkRequest(syscall.RTM_NEWQDISC, syscall.NLM_F_CREATE|syscall.NLM_F_EXCL|syscall.NLM_F_ACK)
|
||||
base := qdisc.Attrs()
|
||||
msg := &nl.TcMsg{
|
||||
Family: nl.FAMILY_ALL,
|
||||
Ifindex: int32(base.LinkIndex),
|
||||
Handle: base.Handle,
|
||||
Parent: base.Parent,
|
||||
}
|
||||
req.AddData(msg)
|
||||
req.AddData(nl.NewRtAttr(nl.TCA_KIND, nl.ZeroTerminated(qdisc.Type())))
|
||||
|
||||
options := nl.NewRtAttr(nl.TCA_OPTIONS, nil)
|
||||
if prio, ok := qdisc.(*Prio); ok {
|
||||
tcmap := nl.TcPrioMap{
|
||||
Bands: int32(prio.Bands),
|
||||
Priomap: prio.PriorityMap,
|
||||
}
|
||||
options = nl.NewRtAttr(nl.TCA_OPTIONS, tcmap.Serialize())
|
||||
} else if tbf, ok := qdisc.(*Tbf); ok {
|
||||
opt := nl.TcTbfQopt{}
|
||||
// TODO: handle rate > uint32
|
||||
opt.Rate.Rate = uint32(tbf.Rate)
|
||||
opt.Limit = tbf.Limit
|
||||
opt.Buffer = tbf.Buffer
|
||||
nl.NewRtAttrChild(options, nl.TCA_TBF_PARMS, opt.Serialize())
|
||||
} else if htb, ok := qdisc.(*Htb); ok {
|
||||
opt := nl.TcHtbGlob{}
|
||||
opt.Version = htb.Version
|
||||
opt.Rate2Quantum = htb.Rate2Quantum
|
||||
opt.Defcls = htb.Defcls
|
||||
// TODO: Handle Debug properly. For now default to 0
|
||||
opt.Debug = htb.Debug
|
||||
opt.DirectPkts = htb.DirectPkts
|
||||
nl.NewRtAttrChild(options, nl.TCA_HTB_INIT, opt.Serialize())
|
||||
// nl.NewRtAttrChild(options, nl.TCA_HTB_DIRECT_QLEN, opt.Serialize())
|
||||
} else if _, ok := qdisc.(*Ingress); ok {
|
||||
// ingress filters must use the proper handle
|
||||
if msg.Parent != HANDLE_INGRESS {
|
||||
return fmt.Errorf("Ingress filters must set Parent to HANDLE_INGRESS")
|
||||
}
|
||||
}
|
||||
req.AddData(options)
|
||||
_, err := req.Execute(syscall.NETLINK_ROUTE, 0)
|
||||
return err
|
||||
}
|
||||
|
||||
// QdiscList gets a list of qdiscs in the system.
|
||||
// Equivalent to: `tc qdisc show`.
|
||||
// The list can be filtered by link.
|
||||
func QdiscList(link Link) ([]Qdisc, error) {
|
||||
req := nl.NewNetlinkRequest(syscall.RTM_GETQDISC, syscall.NLM_F_DUMP)
|
||||
index := int32(0)
|
||||
if link != nil {
|
||||
base := link.Attrs()
|
||||
ensureIndex(base)
|
||||
index = int32(base.Index)
|
||||
}
|
||||
msg := &nl.TcMsg{
|
||||
Family: nl.FAMILY_ALL,
|
||||
Ifindex: index,
|
||||
}
|
||||
req.AddData(msg)
|
||||
|
||||
msgs, err := req.Execute(syscall.NETLINK_ROUTE, syscall.RTM_NEWQDISC)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var res []Qdisc
|
||||
for _, m := range msgs {
|
||||
msg := nl.DeserializeTcMsg(m)
|
||||
|
||||
attrs, err := nl.ParseRouteAttr(m[msg.Len():])
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// skip qdiscs from other interfaces
|
||||
if link != nil && msg.Ifindex != index {
|
||||
continue
|
||||
}
|
||||
|
||||
base := QdiscAttrs{
|
||||
LinkIndex: int(msg.Ifindex),
|
||||
Handle: msg.Handle,
|
||||
Parent: msg.Parent,
|
||||
Refcnt: msg.Info,
|
||||
}
|
||||
var qdisc Qdisc
|
||||
qdiscType := ""
|
||||
for _, attr := range attrs {
|
||||
switch attr.Attr.Type {
|
||||
case nl.TCA_KIND:
|
||||
qdiscType = string(attr.Value[:len(attr.Value)-1])
|
||||
switch qdiscType {
|
||||
case "pfifo_fast":
|
||||
qdisc = &PfifoFast{}
|
||||
case "prio":
|
||||
qdisc = &Prio{}
|
||||
case "tbf":
|
||||
qdisc = &Tbf{}
|
||||
case "ingress":
|
||||
qdisc = &Ingress{}
|
||||
case "htb":
|
||||
qdisc = &Htb{}
|
||||
default:
|
||||
qdisc = &GenericQdisc{QdiscType: qdiscType}
|
||||
}
|
||||
case nl.TCA_OPTIONS:
|
||||
switch qdiscType {
|
||||
case "pfifo_fast":
|
||||
// pfifo returns TcPrioMap directly without wrapping it in rtattr
|
||||
if err := parsePfifoFastData(qdisc, attr.Value); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
case "prio":
|
||||
// prio returns TcPrioMap directly without wrapping it in rtattr
|
||||
if err := parsePrioData(qdisc, attr.Value); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
case "tbf":
|
||||
data, err := nl.ParseRouteAttr(attr.Value)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := parseTbfData(qdisc, data); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
case "htb":
|
||||
data, err := nl.ParseRouteAttr(attr.Value)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := parseHtbData(qdisc, data); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// no options for ingress
|
||||
}
|
||||
}
|
||||
}
|
||||
*qdisc.Attrs() = base
|
||||
res = append(res, qdisc)
|
||||
}
|
||||
|
||||
return res, nil
|
||||
}
|
||||
|
||||
func parsePfifoFastData(qdisc Qdisc, value []byte) error {
|
||||
pfifo := qdisc.(*PfifoFast)
|
||||
tcmap := nl.DeserializeTcPrioMap(value)
|
||||
pfifo.PriorityMap = tcmap.Priomap
|
||||
pfifo.Bands = uint8(tcmap.Bands)
|
||||
return nil
|
||||
}
|
||||
|
||||
func parsePrioData(qdisc Qdisc, value []byte) error {
|
||||
prio := qdisc.(*Prio)
|
||||
tcmap := nl.DeserializeTcPrioMap(value)
|
||||
prio.PriorityMap = tcmap.Priomap
|
||||
prio.Bands = uint8(tcmap.Bands)
|
||||
return nil
|
||||
}
|
||||
|
||||
func parseHtbData(qdisc Qdisc, data []syscall.NetlinkRouteAttr) error {
|
||||
native = nl.NativeEndian()
|
||||
htb := qdisc.(*Htb)
|
||||
for _, datum := range data {
|
||||
switch datum.Attr.Type {
|
||||
case nl.TCA_HTB_INIT:
|
||||
opt := nl.DeserializeTcHtbGlob(datum.Value)
|
||||
htb.Version = opt.Version
|
||||
htb.Rate2Quantum = opt.Rate2Quantum
|
||||
htb.Defcls = opt.Defcls
|
||||
htb.Debug = opt.Debug
|
||||
htb.DirectPkts = opt.DirectPkts
|
||||
case nl.TCA_HTB_DIRECT_QLEN:
|
||||
// TODO
|
||||
//htb.DirectQlen = native.uint32(datum.Value)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
func parseTbfData(qdisc Qdisc, data []syscall.NetlinkRouteAttr) error {
|
||||
native = nl.NativeEndian()
|
||||
tbf := qdisc.(*Tbf)
|
||||
for _, datum := range data {
|
||||
switch datum.Attr.Type {
|
||||
case nl.TCA_TBF_PARMS:
|
||||
opt := nl.DeserializeTcTbfQopt(datum.Value)
|
||||
tbf.Rate = uint64(opt.Rate.Rate)
|
||||
tbf.Limit = opt.Limit
|
||||
tbf.Buffer = opt.Buffer
|
||||
case nl.TCA_TBF_RATE64:
|
||||
tbf.Rate = native.Uint64(datum.Value[0:4])
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
const (
|
||||
TIME_UNITS_PER_SEC = 1000000
|
||||
)
|
||||
|
||||
var (
|
||||
tickInUsec float64 = 0.0
|
||||
clockFactor float64 = 0.0
|
||||
hz float64 = 0.0
|
||||
)
|
||||
|
||||
func initClock() {
|
||||
data, err := ioutil.ReadFile("/proc/net/psched")
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
parts := strings.Split(strings.TrimSpace(string(data)), " ")
|
||||
if len(parts) < 3 {
|
||||
return
|
||||
}
|
||||
var vals [3]uint64
|
||||
for i := range vals {
|
||||
val, err := strconv.ParseUint(parts[i], 16, 32)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
vals[i] = val
|
||||
}
|
||||
// compatibility
|
||||
if vals[2] == 1000000000 {
|
||||
vals[0] = vals[1]
|
||||
}
|
||||
clockFactor = float64(vals[2]) / TIME_UNITS_PER_SEC
|
||||
tickInUsec = float64(vals[0]) / float64(vals[1]) * clockFactor
|
||||
hz = float64(vals[0])
|
||||
}
|
||||
|
||||
func TickInUsec() float64 {
|
||||
if tickInUsec == 0.0 {
|
||||
initClock()
|
||||
}
|
||||
return tickInUsec
|
||||
}
|
||||
|
||||
func ClockFactor() float64 {
|
||||
if clockFactor == 0.0 {
|
||||
initClock()
|
||||
}
|
||||
return clockFactor
|
||||
}
|
||||
|
||||
func Hz() float64 {
|
||||
if hz == 0.0 {
|
||||
initClock()
|
||||
}
|
||||
return hz
|
||||
}
|
||||
|
||||
func time2Tick(time uint32) uint32 {
|
||||
return uint32(float64(time) * TickInUsec())
|
||||
}
|
||||
|
||||
func tick2Time(tick uint32) uint32 {
|
||||
return uint32(float64(tick) / TickInUsec())
|
||||
}
|
||||
|
||||
func time2Ktime(time uint32) uint32 {
|
||||
return uint32(float64(time) * ClockFactor())
|
||||
}
|
||||
|
||||
func ktime2Time(ktime uint32) uint32 {
|
||||
return uint32(float64(ktime) / ClockFactor())
|
||||
}
|
||||
|
||||
func burst(rate uint64, buffer uint32) uint32 {
|
||||
return uint32(float64(rate) * float64(tick2Time(buffer)) / TIME_UNITS_PER_SEC)
|
||||
}
|
||||
|
||||
func latency(rate uint64, limit, buffer uint32) float64 {
|
||||
return TIME_UNITS_PER_SEC*(float64(limit)/float64(rate)) - float64(tick2Time(buffer))
|
||||
}
|
||||
|
||||
func Xmittime(rate uint64, size uint32) float64 {
|
||||
return TickInUsec() * TIME_UNITS_PER_SEC * (float64(size) / float64(rate))
|
||||
}
|
46
libnetwork/Godeps/_workspace/src/github.com/vishvananda/netlink/route.go
generated
vendored
46
libnetwork/Godeps/_workspace/src/github.com/vishvananda/netlink/route.go
generated
vendored
|
@ -17,6 +17,13 @@ const (
|
|||
SCOPE_NOWHERE Scope = syscall.RT_SCOPE_NOWHERE
|
||||
)
|
||||
|
||||
type NextHopFlag int
|
||||
|
||||
const (
|
||||
FLAG_ONLINK NextHopFlag = syscall.RTNH_F_ONLINK
|
||||
FLAG_PERVASIVE NextHopFlag = syscall.RTNH_F_PERVASIVE
|
||||
)
|
||||
|
||||
// Route represents a netlink route. A route is associated with a link,
|
||||
// has a destination network, an optional source ip, and optional
|
||||
// gateway. Advanced route parameters and non-main routing tables are
|
||||
|
@ -27,9 +34,44 @@ type Route struct {
|
|||
Dst *net.IPNet
|
||||
Src net.IP
|
||||
Gw net.IP
|
||||
Flags int
|
||||
}
|
||||
|
||||
func (r Route) String() string {
|
||||
return fmt.Sprintf("{Ifindex: %d Dst: %s Src: %s Gw: %s}", r.LinkIndex, r.Dst,
|
||||
r.Src, r.Gw)
|
||||
return fmt.Sprintf("{Ifindex: %d Dst: %s Src: %s Gw: %s Flags: %s}", r.LinkIndex, r.Dst,
|
||||
r.Src, r.Gw, r.ListFlags())
|
||||
}
|
||||
|
||||
func (r *Route) SetFlag(flag NextHopFlag) {
|
||||
r.Flags |= int(flag)
|
||||
}
|
||||
|
||||
func (r *Route) ClearFlag(flag NextHopFlag) {
|
||||
r.Flags &^= int(flag)
|
||||
}
|
||||
|
||||
type flagString struct {
|
||||
f NextHopFlag
|
||||
s string
|
||||
}
|
||||
|
||||
var testFlags = []flagString{
|
||||
flagString{f: FLAG_ONLINK, s: "onlink"},
|
||||
flagString{f: FLAG_PERVASIVE, s: "pervasive"},
|
||||
}
|
||||
|
||||
func (r *Route) ListFlags() []string {
|
||||
var flags []string
|
||||
for _, tf := range testFlags {
|
||||
if r.Flags&int(tf.f) != 0 {
|
||||
flags = append(flags, tf.s)
|
||||
}
|
||||
}
|
||||
return flags
|
||||
}
|
||||
|
||||
// RouteUpdate is sent when a route changes - type is RTM_NEWROUTE or RTM_DELROUTE
|
||||
type RouteUpdate struct {
|
||||
Type uint16
|
||||
Route
|
||||
}
|
||||
|
|
115
libnetwork/Godeps/_workspace/src/github.com/vishvananda/netlink/route_linux.go
generated
vendored
115
libnetwork/Godeps/_workspace/src/github.com/vishvananda/netlink/route_linux.go
generated
vendored
|
@ -17,7 +17,7 @@ func RouteAdd(route *Route) error {
|
|||
return routeHandle(route, req, nl.NewRtMsg())
|
||||
}
|
||||
|
||||
// RouteAdd will delete a route from the system.
|
||||
// RouteDel will delete a route from the system.
|
||||
// Equivalent to: `ip route del $route`
|
||||
func RouteDel(route *Route) error {
|
||||
req := nl.NewNetlinkRequest(syscall.RTM_DELROUTE, syscall.NLM_F_ACK)
|
||||
|
@ -30,6 +30,7 @@ func routeHandle(route *Route, req *nl.NetlinkRequest, msg *nl.RtMsg) error {
|
|||
}
|
||||
|
||||
msg.Scope = uint8(route.Scope)
|
||||
msg.Flags = uint32(route.Flags)
|
||||
family := -1
|
||||
var rtAttrs []*nl.RtAttr
|
||||
|
||||
|
@ -117,7 +118,6 @@ func RouteList(link Link, family int) ([]Route, error) {
|
|||
index = base.Index
|
||||
}
|
||||
|
||||
native := nl.NativeEndian()
|
||||
var res []Route
|
||||
for _, m := range msgs {
|
||||
msg := nl.DeserializeRtMsg(m)
|
||||
|
@ -132,31 +132,14 @@ func RouteList(link Link, family int) ([]Route, error) {
|
|||
continue
|
||||
}
|
||||
|
||||
attrs, err := nl.ParseRouteAttr(m[msg.Len():])
|
||||
route, err := deserializeRoute(m)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
route := Route{Scope: Scope(msg.Scope)}
|
||||
for _, attr := range attrs {
|
||||
switch attr.Attr.Type {
|
||||
case syscall.RTA_GATEWAY:
|
||||
route.Gw = net.IP(attr.Value)
|
||||
case syscall.RTA_PREFSRC:
|
||||
route.Src = net.IP(attr.Value)
|
||||
case syscall.RTA_DST:
|
||||
route.Dst = &net.IPNet{
|
||||
IP: attr.Value,
|
||||
Mask: net.CIDRMask(int(msg.Dst_len), 8*len(attr.Value)),
|
||||
}
|
||||
case syscall.RTA_OIF:
|
||||
routeIndex := int(native.Uint32(attr.Value[0:4]))
|
||||
if link != nil && routeIndex != index {
|
||||
// Ignore routes from other interfaces
|
||||
continue
|
||||
}
|
||||
route.LinkIndex = routeIndex
|
||||
}
|
||||
if link != nil && route.LinkIndex != index {
|
||||
// Ignore routes from other interfaces
|
||||
continue
|
||||
}
|
||||
res = append(res, route)
|
||||
}
|
||||
|
@ -164,6 +147,37 @@ func RouteList(link Link, family int) ([]Route, error) {
|
|||
return res, nil
|
||||
}
|
||||
|
||||
// deserializeRoute decodes a binary netlink message into a Route struct
|
||||
func deserializeRoute(m []byte) (Route, error) {
|
||||
route := Route{}
|
||||
msg := nl.DeserializeRtMsg(m)
|
||||
attrs, err := nl.ParseRouteAttr(m[msg.Len():])
|
||||
if err != nil {
|
||||
return route, err
|
||||
}
|
||||
route.Scope = Scope(msg.Scope)
|
||||
route.Flags = int(msg.Flags)
|
||||
|
||||
native := nl.NativeEndian()
|
||||
for _, attr := range attrs {
|
||||
switch attr.Attr.Type {
|
||||
case syscall.RTA_GATEWAY:
|
||||
route.Gw = net.IP(attr.Value)
|
||||
case syscall.RTA_PREFSRC:
|
||||
route.Src = net.IP(attr.Value)
|
||||
case syscall.RTA_DST:
|
||||
route.Dst = &net.IPNet{
|
||||
IP: attr.Value,
|
||||
Mask: net.CIDRMask(int(msg.Dst_len), 8*len(attr.Value)),
|
||||
}
|
||||
case syscall.RTA_OIF:
|
||||
routeIndex := int(native.Uint32(attr.Value[0:4]))
|
||||
route.LinkIndex = routeIndex
|
||||
}
|
||||
}
|
||||
return route, nil
|
||||
}
|
||||
|
||||
// RouteGet gets a route to a specific destination from the host system.
|
||||
// Equivalent to: 'ip route get'.
|
||||
func RouteGet(destination net.IP) ([]Route, error) {
|
||||
|
@ -191,34 +205,47 @@ func RouteGet(destination net.IP) ([]Route, error) {
|
|||
return nil, err
|
||||
}
|
||||
|
||||
native := nl.NativeEndian()
|
||||
var res []Route
|
||||
for _, m := range msgs {
|
||||
msg := nl.DeserializeRtMsg(m)
|
||||
attrs, err := nl.ParseRouteAttr(m[msg.Len():])
|
||||
route, err := deserializeRoute(m)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
route := Route{}
|
||||
for _, attr := range attrs {
|
||||
switch attr.Attr.Type {
|
||||
case syscall.RTA_GATEWAY:
|
||||
route.Gw = net.IP(attr.Value)
|
||||
case syscall.RTA_PREFSRC:
|
||||
route.Src = net.IP(attr.Value)
|
||||
case syscall.RTA_DST:
|
||||
route.Dst = &net.IPNet{
|
||||
IP: attr.Value,
|
||||
Mask: net.CIDRMask(int(msg.Dst_len), 8*len(attr.Value)),
|
||||
}
|
||||
case syscall.RTA_OIF:
|
||||
routeIndex := int(native.Uint32(attr.Value[0:4]))
|
||||
route.LinkIndex = routeIndex
|
||||
}
|
||||
}
|
||||
res = append(res, route)
|
||||
}
|
||||
return res, nil
|
||||
|
||||
}
|
||||
|
||||
// RouteSubscribe takes a chan down which notifications will be sent
|
||||
// when routes are added or deleted. Close the 'done' chan to stop subscription.
|
||||
func RouteSubscribe(ch chan<- RouteUpdate, done <-chan struct{}) error {
|
||||
s, err := nl.Subscribe(syscall.NETLINK_ROUTE, syscall.RTNLGRP_IPV4_ROUTE, syscall.RTNLGRP_IPV6_ROUTE)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if done != nil {
|
||||
go func() {
|
||||
<-done
|
||||
s.Close()
|
||||
}()
|
||||
}
|
||||
go func() {
|
||||
defer close(ch)
|
||||
for {
|
||||
msgs, err := s.Receive()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
for _, m := range msgs {
|
||||
route, err := deserializeRoute(m.Data)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
ch <- RouteUpdate{Type: m.Header.Type, Route: route}
|
||||
}
|
||||
}
|
||||
}()
|
||||
|
||||
return nil
|
||||
}
|
||||
|
|
84
libnetwork/Godeps/_workspace/src/github.com/vishvananda/netlink/route_test.go
generated
vendored
84
libnetwork/Godeps/_workspace/src/github.com/vishvananda/netlink/route_test.go
generated
vendored
|
@ -1,84 +0,0 @@
|
|||
package netlink
|
||||
|
||||
import (
|
||||
"net"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestRouteAddDel(t *testing.T) {
|
||||
tearDown := setUpNetlinkTest(t)
|
||||
defer tearDown()
|
||||
|
||||
// get loopback interface
|
||||
link, err := LinkByName("lo")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
// bring the interface up
|
||||
if err = LinkSetUp(link); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
// add a gateway route
|
||||
_, dst, err := net.ParseCIDR("192.168.0.0/24")
|
||||
|
||||
ip := net.ParseIP("127.1.1.1")
|
||||
route := Route{LinkIndex: link.Attrs().Index, Dst: dst, Src: ip}
|
||||
err = RouteAdd(&route)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
routes, err := RouteList(link, FAMILY_V4)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if len(routes) != 1 {
|
||||
t.Fatal("Link not added properly")
|
||||
}
|
||||
|
||||
dstIP := net.ParseIP("192.168.0.42")
|
||||
routeToDstIP, err := RouteGet(dstIP)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if len(routeToDstIP) == 0 {
|
||||
t.Fatal("Default route not present")
|
||||
}
|
||||
|
||||
err = RouteDel(&route)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
routes, err = RouteList(link, FAMILY_V4)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if len(routes) != 0 {
|
||||
t.Fatal("Route not removed properly")
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func TestRouteAddIncomplete(t *testing.T) {
|
||||
tearDown := setUpNetlinkTest(t)
|
||||
defer tearDown()
|
||||
|
||||
// get loopback interface
|
||||
link, err := LinkByName("lo")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
// bring the interface up
|
||||
if err = LinkSetUp(link); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
route := Route{LinkIndex: link.Attrs().Index}
|
||||
if err := RouteAdd(&route); err == nil {
|
||||
t.Fatal("Adding incomplete route should fail")
|
||||
}
|
||||
}
|
49
libnetwork/Godeps/_workspace/src/github.com/vishvananda/netlink/xfrm_policy_test.go
generated
vendored
49
libnetwork/Godeps/_workspace/src/github.com/vishvananda/netlink/xfrm_policy_test.go
generated
vendored
|
@ -1,49 +0,0 @@
|
|||
package netlink
|
||||
|
||||
import (
|
||||
"net"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestXfrmPolicyAddDel(t *testing.T) {
|
||||
tearDown := setUpNetlinkTest(t)
|
||||
defer tearDown()
|
||||
|
||||
src, _ := ParseIPNet("127.1.1.1/32")
|
||||
dst, _ := ParseIPNet("127.1.1.2/32")
|
||||
policy := XfrmPolicy{
|
||||
Src: src,
|
||||
Dst: dst,
|
||||
Dir: XFRM_DIR_OUT,
|
||||
}
|
||||
tmpl := XfrmPolicyTmpl{
|
||||
Src: net.ParseIP("127.0.0.1"),
|
||||
Dst: net.ParseIP("127.0.0.2"),
|
||||
Proto: XFRM_PROTO_ESP,
|
||||
Mode: XFRM_MODE_TUNNEL,
|
||||
}
|
||||
policy.Tmpls = append(policy.Tmpls, tmpl)
|
||||
if err := XfrmPolicyAdd(&policy); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
policies, err := XfrmPolicyList(FAMILY_ALL)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if len(policies) != 1 {
|
||||
t.Fatal("Policy not added properly")
|
||||
}
|
||||
|
||||
if err = XfrmPolicyDel(&policy); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
policies, err = XfrmPolicyList(FAMILY_ALL)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if len(policies) != 0 {
|
||||
t.Fatal("Policy not removed properly")
|
||||
}
|
||||
}
|
50
libnetwork/Godeps/_workspace/src/github.com/vishvananda/netlink/xfrm_state_test.go
generated
vendored
50
libnetwork/Godeps/_workspace/src/github.com/vishvananda/netlink/xfrm_state_test.go
generated
vendored
|
@ -1,50 +0,0 @@
|
|||
package netlink
|
||||
|
||||
import (
|
||||
"net"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestXfrmStateAddDel(t *testing.T) {
|
||||
tearDown := setUpNetlinkTest(t)
|
||||
defer tearDown()
|
||||
|
||||
state := XfrmState{
|
||||
Src: net.ParseIP("127.0.0.1"),
|
||||
Dst: net.ParseIP("127.0.0.2"),
|
||||
Proto: XFRM_PROTO_ESP,
|
||||
Mode: XFRM_MODE_TUNNEL,
|
||||
Spi: 1,
|
||||
Auth: &XfrmStateAlgo{
|
||||
Name: "hmac(sha256)",
|
||||
Key: []byte("abcdefghijklmnopqrstuvwzyzABCDEF"),
|
||||
},
|
||||
Crypt: &XfrmStateAlgo{
|
||||
Name: "cbc(aes)",
|
||||
Key: []byte("abcdefghijklmnopqrstuvwzyzABCDEF"),
|
||||
},
|
||||
}
|
||||
if err := XfrmStateAdd(&state); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
policies, err := XfrmStateList(FAMILY_ALL)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if len(policies) != 1 {
|
||||
t.Fatal("State not added properly")
|
||||
}
|
||||
|
||||
if err = XfrmStateDel(&state); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
policies, err = XfrmStateList(FAMILY_ALL)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if len(policies) != 0 {
|
||||
t.Fatal("State not removed properly")
|
||||
}
|
||||
}
|
7
libnetwork/Godeps/_workspace/src/github.com/vishvananda/netns/netns_linux_s390x.go
generated
vendored
Normal file
7
libnetwork/Godeps/_workspace/src/github.com/vishvananda/netns/netns_linux_s390x.go
generated
vendored
Normal file
|
@ -0,0 +1,7 @@
|
|||
// +build linux,s390x
|
||||
|
||||
package netns
|
||||
|
||||
const (
|
||||
SYS_SETNS = 339
|
||||
)
|
66
libnetwork/Godeps/_workspace/src/github.com/vishvananda/netns/netns_test.go
generated
vendored
66
libnetwork/Godeps/_workspace/src/github.com/vishvananda/netns/netns_test.go
generated
vendored
|
@ -1,66 +0,0 @@
|
|||
package netns
|
||||
|
||||
import (
|
||||
"runtime"
|
||||
"sync"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestGetNewSetDelete(t *testing.T) {
|
||||
runtime.LockOSThread()
|
||||
defer runtime.UnlockOSThread()
|
||||
|
||||
origns, err := Get()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
newns, err := New()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if origns.Equal(newns) {
|
||||
t.Fatal("New ns failed")
|
||||
}
|
||||
if err := Set(origns); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
newns.Close()
|
||||
if newns.IsOpen() {
|
||||
t.Fatal("newns still open after close", newns)
|
||||
}
|
||||
ns, err := Get()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if !ns.Equal(origns) {
|
||||
t.Fatal("Reset ns failed", origns, newns, ns)
|
||||
}
|
||||
}
|
||||
|
||||
func TestNone(t *testing.T) {
|
||||
ns := None()
|
||||
if ns.IsOpen() {
|
||||
t.Fatal("None ns is open", ns)
|
||||
}
|
||||
}
|
||||
|
||||
func TestThreaded(t *testing.T) {
|
||||
ncpu := runtime.GOMAXPROCS(-1)
|
||||
if ncpu < 2 {
|
||||
t.Skip("-cpu=2 or larger required")
|
||||
}
|
||||
|
||||
// Lock this thread simply to ensure other threads get used.
|
||||
runtime.LockOSThread()
|
||||
defer runtime.UnlockOSThread()
|
||||
|
||||
wg := &sync.WaitGroup{}
|
||||
for i := 0; i < ncpu; i++ {
|
||||
wg.Add(1)
|
||||
go func() {
|
||||
defer wg.Done()
|
||||
TestGetNewSetDelete(t)
|
||||
}()
|
||||
}
|
||||
wg.Wait()
|
||||
}
|
Loading…
Add table
Reference in a new issue