mirror of https://github.com/docker/docs.git
				
				
				
			Vendoring vishvananda/netlink 734d02c
Signed-off-by: Alessandro Boch <aboch@docker.com> (cherry picked from commit 58b8b8fa1555223c1144f08fc4536ffaa4d12fd0)
This commit is contained in:
		
							parent
							
								
									ae0648fca8
								
							
						
					
					
						commit
						e928358dfb
					
				|  | @ -75,7 +75,7 @@ clone git github.com/hashicorp/go-multierror fcdddc395df1ddf4247c69bd436e84cfa07 | |||
| clone git github.com/hashicorp/serf 598c54895cc5a7b1a24a398d635e8c0ea0959870 | ||||
| clone git github.com/docker/libkv 7283ef27ed32fe267388510a91709b307bb9942c | ||||
| clone git github.com/vishvananda/netns 604eaf189ee867d8c147fafc28def2394e878d25 | ||||
| clone git github.com/vishvananda/netlink 7995ff5647a22cbf0dc41bf5c0e977bdb0d5c6b7 | ||||
| clone git github.com/vishvananda/netlink 734d02c3e202f682c74b71314b2c61eec0170fd4 | ||||
| clone git github.com/BurntSushi/toml f706d00e3de6abe700c994cdd545a1a4915af060 | ||||
| clone git github.com/samuel/go-zookeeper d0e0d8e11f318e000a8cc434616d69e329edc374 | ||||
| clone git github.com/deckarep/golang-set ef32fa3046d9f249d399f98ebaf9be944430fd1d | ||||
|  |  | |||
|  | @ -8,7 +8,7 @@ the kernel. It can be used to add and remove interfaces, set ip addresses | |||
| and routes, and configure ipsec. Netlink communication requires elevated | ||||
| privileges, so in most cases this code needs to be run as root. Since | ||||
| low-level netlink messages are inscrutable at best, the library attempts | ||||
| to provide an api that is loosely modeled on the CLI provied by iproute2. | ||||
| to provide an api that is loosely modeled on the CLI provided by iproute2. | ||||
| Actions like `ip link add` will be accomplished via a similarly named | ||||
| function like AddLink(). This library began its life as a fork of the | ||||
| netlink functionality in | ||||
|  |  | |||
|  | @ -50,39 +50,6 @@ type HtbClass struct { | |||
| 	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) | ||||
| } | ||||
|  |  | |||
|  | @ -7,6 +7,40 @@ import ( | |||
| 	"github.com/vishvananda/netlink/nl" | ||||
| ) | ||||
| 
 | ||||
| // NOTE: function is in here because it uses other linux functions
 | ||||
| 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, | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| // ClassDel will delete a class from the system.
 | ||||
| // Equivalent to: `tc class del $class`
 | ||||
| func ClassDel(class Class) error { | ||||
|  |  | |||
|  | @ -1,11 +1,6 @@ | |||
| package netlink | ||||
| 
 | ||||
| import ( | ||||
| 	"errors" | ||||
| 	"fmt" | ||||
| 
 | ||||
| 	"github.com/vishvananda/netlink/nl" | ||||
| ) | ||||
| import "fmt" | ||||
| 
 | ||||
| type Filter interface { | ||||
| 	Attrs() *FilterAttrs | ||||
|  | @ -217,74 +212,6 @@ type FilterFwAttrs struct { | |||
| 	LinkLayer int | ||||
| } | ||||
| 
 | ||||
| // Fw filter filters on firewall marks
 | ||||
| type Fw struct { | ||||
| 	FilterAttrs | ||||
| 	ClassId uint32 | ||||
| 	// TODO remove nl type from interface
 | ||||
| 	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 | ||||
| 	rcellLog := -1 | ||||
| 	pcellLog := -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, rcellLog, 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, pcellLog, 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" | ||||
| } | ||||
| 
 | ||||
| type BpfFilter struct { | ||||
| 	FilterAttrs | ||||
| 	ClassId      uint32 | ||||
|  |  | |||
|  | @ -3,12 +3,83 @@ package netlink | |||
| import ( | ||||
| 	"bytes" | ||||
| 	"encoding/binary" | ||||
| 	"errors" | ||||
| 	"fmt" | ||||
| 	"syscall" | ||||
| 
 | ||||
| 	"github.com/vishvananda/netlink/nl" | ||||
| ) | ||||
| 
 | ||||
| // Fw filter filters on firewall marks
 | ||||
| // NOTE: this is in filter_linux because it refers to nl.TcPolice which
 | ||||
| //       is defined in nl/tc_linux.go
 | ||||
| type Fw struct { | ||||
| 	FilterAttrs | ||||
| 	ClassId uint32 | ||||
| 	// TODO remove nl type from interface
 | ||||
| 	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 | ||||
| 	rcellLog := -1 | ||||
| 	pcellLog := -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, rcellLog, 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, pcellLog, 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" | ||||
| } | ||||
| 
 | ||||
| // FilterDel will delete a filter from the system.
 | ||||
| // Equivalent to: `tc filter del $filter`
 | ||||
| func FilterDel(filter Filter) error { | ||||
|  | @ -126,14 +197,14 @@ func (h *Handle) FilterAdd(filter Filter) error { | |||
| 
 | ||||
| // FilterList gets a list of filters in the system.
 | ||||
| // Equivalent to: `tc filter show`.
 | ||||
| // Generally retunrs nothing if link and parent are not specified.
 | ||||
| // Generally returns nothing if link and parent are not specified.
 | ||||
| func FilterList(link Link, parent uint32) ([]Filter, error) { | ||||
| 	return pkgHandle.FilterList(link, parent) | ||||
| } | ||||
| 
 | ||||
| // FilterList gets a list of filters in the system.
 | ||||
| // Equivalent to: `tc filter show`.
 | ||||
| // Generally retunrs nothing if link and parent are not specified.
 | ||||
| // Generally returns nothing if link and parent are not specified.
 | ||||
| func (h *Handle) FilterList(link Link, parent uint32) ([]Filter, error) { | ||||
| 	req := h.newNetlinkRequest(syscall.RTM_GETTFILTER, syscall.NLM_F_DUMP) | ||||
| 	msg := &nl.TcMsg{ | ||||
|  |  | |||
|  | @ -1,86 +0,0 @@ | |||
| package netlink | ||||
| 
 | ||||
| import ( | ||||
| 	"sync/atomic" | ||||
| 	"syscall" | ||||
| 
 | ||||
| 	"github.com/vishvananda/netlink/nl" | ||||
| 	"github.com/vishvananda/netns" | ||||
| ) | ||||
| 
 | ||||
| // Empty handle used by the netlink package methods
 | ||||
| var pkgHandle = &Handle{} | ||||
| 
 | ||||
| // Handle is an handle for the netlink requests
 | ||||
| // on a specific network namespace. All the requests
 | ||||
| // share the same netlink socket, which gets released
 | ||||
| // when the handle is deleted.
 | ||||
| type Handle struct { | ||||
| 	seq          uint32 | ||||
| 	routeSocket  *nl.NetlinkSocket | ||||
| 	xfrmSocket   *nl.NetlinkSocket | ||||
| 	lookupByDump bool | ||||
| } | ||||
| 
 | ||||
| // NewHandle returns a netlink handle on the current network namespace.
 | ||||
| func NewHandle() (*Handle, error) { | ||||
| 	return newHandle(netns.None(), netns.None()) | ||||
| } | ||||
| 
 | ||||
| // NewHandle returns a netlink handle on the network namespace
 | ||||
| // specified by ns. If ns=netns.None(), current network namespace
 | ||||
| // will be assumed
 | ||||
| func NewHandleAt(ns netns.NsHandle) (*Handle, error) { | ||||
| 	return newHandle(ns, netns.None()) | ||||
| } | ||||
| 
 | ||||
| // NewHandleAtFrom works as NewHandle but allows client to specify the
 | ||||
| // new and the origin netns Handle.
 | ||||
| func NewHandleAtFrom(newNs, curNs netns.NsHandle) (*Handle, error) { | ||||
| 	return newHandle(newNs, curNs) | ||||
| } | ||||
| 
 | ||||
| func newHandle(newNs, curNs netns.NsHandle) (*Handle, error) { | ||||
| 	var ( | ||||
| 		err     error | ||||
| 		rSocket *nl.NetlinkSocket | ||||
| 		xSocket *nl.NetlinkSocket | ||||
| 	) | ||||
| 	rSocket, err = nl.GetNetlinkSocketAt(newNs, curNs, syscall.NETLINK_ROUTE) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
| 	xSocket, err = nl.GetNetlinkSocketAt(newNs, curNs, syscall.NETLINK_XFRM) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
| 	return &Handle{routeSocket: rSocket, xfrmSocket: xSocket}, nil | ||||
| } | ||||
| 
 | ||||
| // Delete releases the resources allocated to this handle
 | ||||
| func (h *Handle) Delete() { | ||||
| 	if h.routeSocket != nil { | ||||
| 		h.routeSocket.Close() | ||||
| 	} | ||||
| 	if h.xfrmSocket != nil { | ||||
| 		h.xfrmSocket.Close() | ||||
| 	} | ||||
| 	h.routeSocket, h.xfrmSocket = nil, nil | ||||
| } | ||||
| 
 | ||||
| func (h *Handle) newNetlinkRequest(proto, flags int) *nl.NetlinkRequest { | ||||
| 	// Do this so that package API still use nl package variable nextSeqNr
 | ||||
| 	if h.routeSocket == nil { | ||||
| 		return nl.NewNetlinkRequest(proto, flags) | ||||
| 	} | ||||
| 	return &nl.NetlinkRequest{ | ||||
| 		NlMsghdr: syscall.NlMsghdr{ | ||||
| 			Len:   uint32(syscall.SizeofNlMsghdr), | ||||
| 			Type:  uint16(proto), | ||||
| 			Flags: syscall.NLM_F_REQUEST | uint16(flags), | ||||
| 			Seq:   atomic.AddUint32(&h.seq, 1), | ||||
| 		}, | ||||
| 		RouteSocket: h.routeSocket, | ||||
| 		XfmrSocket:  h.xfrmSocket, | ||||
| 	} | ||||
| } | ||||
|  | @ -0,0 +1,86 @@ | |||
| package netlink | ||||
| 
 | ||||
| import ( | ||||
| 	"syscall" | ||||
| 
 | ||||
| 	"github.com/vishvananda/netlink/nl" | ||||
| 	"github.com/vishvananda/netns" | ||||
| ) | ||||
| 
 | ||||
| // Empty handle used by the netlink package methods
 | ||||
| var pkgHandle = &Handle{} | ||||
| 
 | ||||
| // Handle is an handle for the netlink requests on a
 | ||||
| // specific network namespace. All the requests on the
 | ||||
| // same netlink family share the same netlink socket,
 | ||||
| // which gets released when the handle is deleted.
 | ||||
| type Handle struct { | ||||
| 	sockets      map[int]*nl.SocketHandle | ||||
| 	lookupByDump bool | ||||
| } | ||||
| 
 | ||||
| // SupportsNetlinkFamily reports whether the passed netlink family is supported by this Handle
 | ||||
| func (h *Handle) SupportsNetlinkFamily(nlFamily int) bool { | ||||
| 	_, ok := h.sockets[nlFamily] | ||||
| 	return ok | ||||
| } | ||||
| 
 | ||||
| // NewHandle returns a netlink handle on the current network namespace.
 | ||||
| // Caller may specify the netlink families the handle should support.
 | ||||
| // If no families are specified, all the families the netlink package
 | ||||
| // supports will be automatically added.
 | ||||
| func NewHandle(nlFamilies ...int) (*Handle, error) { | ||||
| 	return newHandle(netns.None(), netns.None(), nlFamilies...) | ||||
| } | ||||
| 
 | ||||
| // NewHandle returns a netlink handle on the network namespace
 | ||||
| // specified by ns. If ns=netns.None(), current network namespace
 | ||||
| // will be assumed
 | ||||
| func NewHandleAt(ns netns.NsHandle, nlFamilies ...int) (*Handle, error) { | ||||
| 	return newHandle(ns, netns.None(), nlFamilies...) | ||||
| } | ||||
| 
 | ||||
| // NewHandleAtFrom works as NewHandle but allows client to specify the
 | ||||
| // new and the origin netns Handle.
 | ||||
| func NewHandleAtFrom(newNs, curNs netns.NsHandle) (*Handle, error) { | ||||
| 	return newHandle(newNs, curNs) | ||||
| } | ||||
| 
 | ||||
| func newHandle(newNs, curNs netns.NsHandle, nlFamilies ...int) (*Handle, error) { | ||||
| 	h := &Handle{sockets: map[int]*nl.SocketHandle{}} | ||||
| 	fams := nl.SupportedNlFamilies | ||||
| 	if len(nlFamilies) != 0 { | ||||
| 		fams = nlFamilies | ||||
| 	} | ||||
| 	for _, f := range fams { | ||||
| 		s, err := nl.GetNetlinkSocketAt(newNs, curNs, f) | ||||
| 		if err != nil { | ||||
| 			return nil, err | ||||
| 		} | ||||
| 		h.sockets[f] = &nl.SocketHandle{Socket: s} | ||||
| 	} | ||||
| 	return h, nil | ||||
| } | ||||
| 
 | ||||
| // Delete releases the resources allocated to this handle
 | ||||
| func (h *Handle) Delete() { | ||||
| 	for _, sh := range h.sockets { | ||||
| 		sh.Close() | ||||
| 	} | ||||
| 	h.sockets = nil | ||||
| } | ||||
| 
 | ||||
| func (h *Handle) newNetlinkRequest(proto, flags int) *nl.NetlinkRequest { | ||||
| 	// Do this so that package API still use nl package variable nextSeqNr
 | ||||
| 	if h.sockets == nil { | ||||
| 		return nl.NewNetlinkRequest(proto, flags) | ||||
| 	} | ||||
| 	return &nl.NetlinkRequest{ | ||||
| 		NlMsghdr: syscall.NlMsghdr{ | ||||
| 			Len:   uint32(syscall.SizeofNlMsghdr), | ||||
| 			Type:  uint16(proto), | ||||
| 			Flags: syscall.NLM_F_REQUEST | uint16(flags), | ||||
| 		}, | ||||
| 		Sockets: h.sockets, | ||||
| 	} | ||||
| } | ||||
|  | @ -3,7 +3,6 @@ package netlink | |||
| import ( | ||||
| 	"fmt" | ||||
| 	"net" | ||||
| 	"syscall" | ||||
| ) | ||||
| 
 | ||||
| // Link represents a link device from netlink. Shared link attributes
 | ||||
|  | @ -173,11 +172,6 @@ func (macvtap Macvtap) Type() string { | |||
| 
 | ||||
| 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 | ||||
|  |  | |||
|  | @ -14,6 +14,11 @@ import ( | |||
| 
 | ||||
| const SizeofLinkStats = 0x5c | ||||
| 
 | ||||
| const ( | ||||
| 	TUNTAP_MODE_TUN TuntapMode = syscall.IFF_TUN | ||||
| 	TUNTAP_MODE_TAP TuntapMode = syscall.IFF_TAP | ||||
| ) | ||||
| 
 | ||||
| var native = nl.NativeEndian() | ||||
| var lookupByDump = false | ||||
| 
 | ||||
|  | @ -675,6 +680,11 @@ func (h *Handle) LinkAdd(link Link) error { | |||
| 			data := nl.NewRtAttrChild(linkInfo, nl.IFLA_INFO_DATA, nil) | ||||
| 			nl.NewRtAttrChild(data, nl.IFLA_MACVLAN_MODE, nl.Uint32Attr(macvlanModes[macv.Mode])) | ||||
| 		} | ||||
| 	} else if macv, ok := link.(*Macvtap); ok { | ||||
| 		if macv.Mode != MACVLAN_MODE_DEFAULT { | ||||
| 			data := nl.NewRtAttrChild(linkInfo, nl.IFLA_INFO_DATA, nil) | ||||
| 			nl.NewRtAttrChild(data, nl.IFLA_MACVLAN_MODE, nl.Uint32Attr(macvlanModes[macv.Mode])) | ||||
| 		} | ||||
| 	} else if gretap, ok := link.(*Gretap); ok { | ||||
| 		addGretapAttrs(gretap, linkInfo) | ||||
| 	} | ||||
|  |  | |||
|  | @ -8,18 +8,7 @@ | |||
| // interface that is loosly modeled on the iproute2 cli.
 | ||||
| package netlink | ||||
| 
 | ||||
| import ( | ||||
| 	"net" | ||||
| 
 | ||||
| 	"github.com/vishvananda/netlink/nl" | ||||
| ) | ||||
| 
 | ||||
| // Family type definitions
 | ||||
| const ( | ||||
| 	FAMILY_ALL = nl.FAMILY_ALL | ||||
| 	FAMILY_V4  = nl.FAMILY_V4 | ||||
| 	FAMILY_V6  = nl.FAMILY_V6 | ||||
| ) | ||||
| import "net" | ||||
| 
 | ||||
| // ParseIPNet parses a string in ip/net format and returns a net.IPNet.
 | ||||
| // This is valuable because addresses in netlink are often IPNets and
 | ||||
|  |  | |||
|  | @ -0,0 +1,10 @@ | |||
| package netlink | ||||
| 
 | ||||
| import "github.com/vishvananda/netlink/nl" | ||||
| 
 | ||||
| // Family type definitions
 | ||||
| const ( | ||||
| 	FAMILY_ALL = nl.FAMILY_ALL | ||||
| 	FAMILY_V4  = nl.FAMILY_V4 | ||||
| 	FAMILY_V6  = nl.FAMILY_V6 | ||||
| ) | ||||
|  | @ -138,6 +138,6 @@ func NeighList(linkIndex, family int) ([]Neigh, error) { | |||
| 	return nil, ErrNotImplemented | ||||
| } | ||||
| 
 | ||||
| func NeighDeserialize(m []byte) (*Ndmsg, *Neigh, error) { | ||||
| 	return nil, nil, ErrNotImplemented | ||||
| func NeighDeserialize(m []byte) (*Neigh, error) { | ||||
| 	return nil, ErrNotImplemented | ||||
| } | ||||
|  |  | |||
|  | @ -22,6 +22,9 @@ const ( | |||
| 	FAMILY_V6  = syscall.AF_INET6 | ||||
| ) | ||||
| 
 | ||||
| // SupportedNlFamilies contains the list of netlink families this netlink package supports
 | ||||
| var SupportedNlFamilies = []int{syscall.NETLINK_ROUTE, syscall.NETLINK_XFRM} | ||||
| 
 | ||||
| var nextSeqNr uint32 | ||||
| 
 | ||||
| // GetIPFamily returns the family type of a net.IP.
 | ||||
|  | @ -175,9 +178,8 @@ func (a *RtAttr) Serialize() []byte { | |||
| 
 | ||||
| type NetlinkRequest struct { | ||||
| 	syscall.NlMsghdr | ||||
| 	Data        []NetlinkRequestData | ||||
| 	RouteSocket *NetlinkSocket | ||||
| 	XfmrSocket  *NetlinkSocket | ||||
| 	Data    []NetlinkRequestData | ||||
| 	Sockets map[int]*SocketHandle | ||||
| } | ||||
| 
 | ||||
| // Serialize the Netlink Request into a byte array
 | ||||
|  | @ -209,7 +211,7 @@ func (req *NetlinkRequest) AddData(data NetlinkRequestData) { | |||
| } | ||||
| 
 | ||||
| // Execute the request against a the given sockType.
 | ||||
| // Returns a list of netlink messages in seriaized format, optionally filtered
 | ||||
| // Returns a list of netlink messages in serialized format, optionally filtered
 | ||||
| // by resType.
 | ||||
| func (req *NetlinkRequest) Execute(sockType int, resType uint16) ([][]byte, error) { | ||||
| 	var ( | ||||
|  | @ -217,15 +219,12 @@ func (req *NetlinkRequest) Execute(sockType int, resType uint16) ([][]byte, erro | |||
| 		err error | ||||
| 	) | ||||
| 
 | ||||
| 	switch sockType { | ||||
| 	case syscall.NETLINK_XFRM: | ||||
| 		s = req.XfmrSocket | ||||
| 	case syscall.NETLINK_ROUTE: | ||||
| 		s = req.RouteSocket | ||||
| 	default: | ||||
| 		return nil, fmt.Errorf("Socket type %d is not handled", sockType) | ||||
| 	if req.Sockets != nil { | ||||
| 		if sh, ok := req.Sockets[sockType]; ok { | ||||
| 			s = sh.Socket | ||||
| 			req.Seq = atomic.AddUint32(&sh.Seq, 1) | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	sharedSocket := s != nil | ||||
| 
 | ||||
| 	if s == nil { | ||||
|  | @ -486,3 +485,17 @@ func netlinkRouteAttrAndValue(b []byte) (*syscall.RtAttr, []byte, int, error) { | |||
| 	} | ||||
| 	return a, b[syscall.SizeofRtAttr:], rtaAlignOf(int(a.Len)), nil | ||||
| } | ||||
| 
 | ||||
| // SocketHandle contains the netlink socket and the associated
 | ||||
| // sequence counter for a specific netlink family
 | ||||
| type SocketHandle struct { | ||||
| 	Seq    uint32 | ||||
| 	Socket *NetlinkSocket | ||||
| } | ||||
| 
 | ||||
| // Close closes the netlink socket
 | ||||
| func (sh *SocketHandle) Close() { | ||||
| 	if sh.Socket != nil { | ||||
| 		sh.Socket.Close() | ||||
| 	} | ||||
| } | ||||
|  |  | |||
|  | @ -40,3 +40,15 @@ func DeserializeRtMsg(b []byte) *RtMsg { | |||
| func (msg *RtMsg) Serialize() []byte { | ||||
| 	return (*(*[syscall.SizeofRtMsg]byte)(unsafe.Pointer(msg)))[:] | ||||
| } | ||||
| 
 | ||||
| type RtNexthop struct { | ||||
| 	syscall.RtNexthop | ||||
| } | ||||
| 
 | ||||
| func DeserializeRtNexthop(b []byte) *RtNexthop { | ||||
| 	return (*RtNexthop)(unsafe.Pointer(&b[0:syscall.SizeofRtNexthop][0])) | ||||
| } | ||||
| 
 | ||||
| func (msg *RtNexthop) Serialize() []byte { | ||||
| 	return (*(*[syscall.SizeofRtNexthop]byte)(unsafe.Pointer(msg)))[:] | ||||
| } | ||||
|  |  | |||
|  | @ -176,70 +176,6 @@ type Netem struct { | |||
| 	CorruptCorr   uint32 | ||||
| } | ||||
| 
 | ||||
| func NewNetem(attrs QdiscAttrs, nattrs NetemQdiscAttrs) *Netem { | ||||
| 	var limit uint32 = 1000 | ||||
| 	var lossCorr, delayCorr, duplicateCorr uint32 | ||||
| 	var reorderProb, reorderCorr uint32 | ||||
| 	var corruptProb, corruptCorr uint32 | ||||
| 
 | ||||
| 	latency := nattrs.Latency | ||||
| 	loss := Percentage2u32(nattrs.Loss) | ||||
| 	gap := nattrs.Gap | ||||
| 	duplicate := Percentage2u32(nattrs.Duplicate) | ||||
| 	jitter := nattrs.Jitter | ||||
| 
 | ||||
| 	// Correlation
 | ||||
| 	if latency > 0 && jitter > 0 { | ||||
| 		delayCorr = Percentage2u32(nattrs.DelayCorr) | ||||
| 	} | ||||
| 	if loss > 0 { | ||||
| 		lossCorr = Percentage2u32(nattrs.LossCorr) | ||||
| 	} | ||||
| 	if duplicate > 0 { | ||||
| 		duplicateCorr = Percentage2u32(nattrs.DuplicateCorr) | ||||
| 	} | ||||
| 	// FIXME should validate values(like loss/duplicate are percentages...)
 | ||||
| 	latency = time2Tick(latency) | ||||
| 
 | ||||
| 	if nattrs.Limit != 0 { | ||||
| 		limit = nattrs.Limit | ||||
| 	} | ||||
| 	// Jitter is only value if latency is > 0
 | ||||
| 	if latency > 0 { | ||||
| 		jitter = time2Tick(jitter) | ||||
| 	} | ||||
| 
 | ||||
| 	reorderProb = Percentage2u32(nattrs.ReorderProb) | ||||
| 	reorderCorr = Percentage2u32(nattrs.ReorderCorr) | ||||
| 
 | ||||
| 	if reorderProb > 0 { | ||||
| 		// ERROR if lantency == 0
 | ||||
| 		if gap == 0 { | ||||
| 			gap = 1 | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	corruptProb = Percentage2u32(nattrs.CorruptProb) | ||||
| 	corruptCorr = Percentage2u32(nattrs.CorruptCorr) | ||||
| 
 | ||||
| 	return &Netem{ | ||||
| 		QdiscAttrs:    attrs, | ||||
| 		Latency:       latency, | ||||
| 		DelayCorr:     delayCorr, | ||||
| 		Limit:         limit, | ||||
| 		Loss:          loss, | ||||
| 		LossCorr:      lossCorr, | ||||
| 		Gap:           gap, | ||||
| 		Duplicate:     duplicate, | ||||
| 		DuplicateCorr: duplicateCorr, | ||||
| 		Jitter:        jitter, | ||||
| 		ReorderProb:   reorderProb, | ||||
| 		ReorderCorr:   reorderCorr, | ||||
| 		CorruptProb:   corruptProb, | ||||
| 		CorruptCorr:   corruptCorr, | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| func (qdisc *Netem) Attrs() *QdiscAttrs { | ||||
| 	return &qdisc.QdiscAttrs | ||||
| } | ||||
|  |  | |||
|  | @ -10,6 +10,71 @@ import ( | |||
| 	"github.com/vishvananda/netlink/nl" | ||||
| ) | ||||
| 
 | ||||
| // NOTE function is here because it uses other linux functions
 | ||||
| func NewNetem(attrs QdiscAttrs, nattrs NetemQdiscAttrs) *Netem { | ||||
| 	var limit uint32 = 1000 | ||||
| 	var lossCorr, delayCorr, duplicateCorr uint32 | ||||
| 	var reorderProb, reorderCorr uint32 | ||||
| 	var corruptProb, corruptCorr uint32 | ||||
| 
 | ||||
| 	latency := nattrs.Latency | ||||
| 	loss := Percentage2u32(nattrs.Loss) | ||||
| 	gap := nattrs.Gap | ||||
| 	duplicate := Percentage2u32(nattrs.Duplicate) | ||||
| 	jitter := nattrs.Jitter | ||||
| 
 | ||||
| 	// Correlation
 | ||||
| 	if latency > 0 && jitter > 0 { | ||||
| 		delayCorr = Percentage2u32(nattrs.DelayCorr) | ||||
| 	} | ||||
| 	if loss > 0 { | ||||
| 		lossCorr = Percentage2u32(nattrs.LossCorr) | ||||
| 	} | ||||
| 	if duplicate > 0 { | ||||
| 		duplicateCorr = Percentage2u32(nattrs.DuplicateCorr) | ||||
| 	} | ||||
| 	// FIXME should validate values(like loss/duplicate are percentages...)
 | ||||
| 	latency = time2Tick(latency) | ||||
| 
 | ||||
| 	if nattrs.Limit != 0 { | ||||
| 		limit = nattrs.Limit | ||||
| 	} | ||||
| 	// Jitter is only value if latency is > 0
 | ||||
| 	if latency > 0 { | ||||
| 		jitter = time2Tick(jitter) | ||||
| 	} | ||||
| 
 | ||||
| 	reorderProb = Percentage2u32(nattrs.ReorderProb) | ||||
| 	reorderCorr = Percentage2u32(nattrs.ReorderCorr) | ||||
| 
 | ||||
| 	if reorderProb > 0 { | ||||
| 		// ERROR if lantency == 0
 | ||||
| 		if gap == 0 { | ||||
| 			gap = 1 | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	corruptProb = Percentage2u32(nattrs.CorruptProb) | ||||
| 	corruptCorr = Percentage2u32(nattrs.CorruptCorr) | ||||
| 
 | ||||
| 	return &Netem{ | ||||
| 		QdiscAttrs:    attrs, | ||||
| 		Latency:       latency, | ||||
| 		DelayCorr:     delayCorr, | ||||
| 		Limit:         limit, | ||||
| 		Loss:          loss, | ||||
| 		LossCorr:      lossCorr, | ||||
| 		Gap:           gap, | ||||
| 		Duplicate:     duplicate, | ||||
| 		DuplicateCorr: duplicateCorr, | ||||
| 		Jitter:        jitter, | ||||
| 		ReorderProb:   reorderProb, | ||||
| 		ReorderCorr:   reorderCorr, | ||||
| 		CorruptProb:   corruptProb, | ||||
| 		CorruptCorr:   corruptCorr, | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| // QdiscDel will delete a qdisc from the system.
 | ||||
| // Equivalent to: `tc qdisc del $qdisc`
 | ||||
| func QdiscDel(qdisc Qdisc) error { | ||||
|  |  | |||
|  | @ -3,27 +3,13 @@ package netlink | |||
| import ( | ||||
| 	"fmt" | ||||
| 	"net" | ||||
| 	"syscall" | ||||
| ) | ||||
| 
 | ||||
| // Scope is an enum representing a route scope.
 | ||||
| type Scope uint8 | ||||
| 
 | ||||
| const ( | ||||
| 	SCOPE_UNIVERSE Scope = syscall.RT_SCOPE_UNIVERSE | ||||
| 	SCOPE_SITE     Scope = syscall.RT_SCOPE_SITE | ||||
| 	SCOPE_LINK     Scope = syscall.RT_SCOPE_LINK | ||||
| 	SCOPE_HOST     Scope = syscall.RT_SCOPE_HOST | ||||
| 	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.
 | ||||
| type Route struct { | ||||
| 	LinkIndex  int | ||||
|  | @ -32,6 +18,7 @@ type Route struct { | |||
| 	Dst        *net.IPNet | ||||
| 	Src        net.IP | ||||
| 	Gw         net.IP | ||||
| 	MultiPath  []*NexthopInfo | ||||
| 	Protocol   int | ||||
| 	Priority   int | ||||
| 	Table      int | ||||
|  | @ -41,6 +28,10 @@ type Route struct { | |||
| } | ||||
| 
 | ||||
| func (r Route) String() string { | ||||
| 	if len(r.MultiPath) > 0 { | ||||
| 		return fmt.Sprintf("{Dst: %s Src: %s Gw: %s Flags: %s Table: %d}", r.Dst, | ||||
| 			r.Src, r.MultiPath, r.ListFlags(), r.Table) | ||||
| 	} | ||||
| 	return fmt.Sprintf("{Ifindex: %d Dst: %s Src: %s Gw: %s Flags: %s Table: %d}", r.LinkIndex, r.Dst, | ||||
| 		r.Src, r.Gw, r.ListFlags(), r.Table) | ||||
| } | ||||
|  | @ -58,23 +49,18 @@ type flagString struct { | |||
| 	s string | ||||
| } | ||||
| 
 | ||||
| var testFlags = []flagString{ | ||||
| 	{f: FLAG_ONLINK, s: "onlink"}, | ||||
| 	{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 | ||||
| } | ||||
| 
 | ||||
| type NexthopInfo struct { | ||||
| 	LinkIndex int | ||||
| 	Hops      int | ||||
| 	Gw        net.IP | ||||
| } | ||||
| 
 | ||||
| func (n *NexthopInfo) String() string { | ||||
| 	return fmt.Sprintf("{Ifindex: %d Weight: %d, Gw: %s}", n.LinkIndex, n.Hops+1, n.Gw) | ||||
| } | ||||
|  |  | |||
|  | @ -10,6 +10,14 @@ import ( | |||
| 
 | ||||
| // RtAttr is shared so it is in netlink_linux.go
 | ||||
| 
 | ||||
| const ( | ||||
| 	SCOPE_UNIVERSE Scope = syscall.RT_SCOPE_UNIVERSE | ||||
| 	SCOPE_SITE     Scope = syscall.RT_SCOPE_SITE | ||||
| 	SCOPE_LINK     Scope = syscall.RT_SCOPE_LINK | ||||
| 	SCOPE_HOST     Scope = syscall.RT_SCOPE_HOST | ||||
| 	SCOPE_NOWHERE  Scope = syscall.RT_SCOPE_NOWHERE | ||||
| ) | ||||
| 
 | ||||
| const ( | ||||
| 	RT_FILTER_PROTOCOL uint64 = 1 << (1 + iota) | ||||
| 	RT_FILTER_SCOPE | ||||
|  | @ -23,6 +31,26 @@ const ( | |||
| 	RT_FILTER_TABLE | ||||
| ) | ||||
| 
 | ||||
| const ( | ||||
| 	FLAG_ONLINK    NextHopFlag = syscall.RTNH_F_ONLINK | ||||
| 	FLAG_PERVASIVE NextHopFlag = syscall.RTNH_F_PERVASIVE | ||||
| ) | ||||
| 
 | ||||
| var testFlags = []flagString{ | ||||
| 	{f: FLAG_ONLINK, s: "onlink"}, | ||||
| 	{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 | ||||
| } | ||||
| 
 | ||||
| // RouteAdd will add a route to the system.
 | ||||
| // Equivalent to: `ip route add $route`
 | ||||
| func RouteAdd(route *Route) error { | ||||
|  | @ -102,6 +130,37 @@ func (h *Handle) routeHandle(route *Route, req *nl.NetlinkRequest, msg *nl.RtMsg | |||
| 		rtAttrs = append(rtAttrs, nl.NewRtAttr(syscall.RTA_GATEWAY, gwData)) | ||||
| 	} | ||||
| 
 | ||||
| 	if len(route.MultiPath) > 0 { | ||||
| 		buf := []byte{} | ||||
| 		for _, nh := range route.MultiPath { | ||||
| 			rtnh := &nl.RtNexthop{ | ||||
| 				RtNexthop: syscall.RtNexthop{ | ||||
| 					Hops:    uint8(nh.Hops), | ||||
| 					Ifindex: int32(nh.LinkIndex), | ||||
| 					Len:     uint16(syscall.SizeofRtNexthop), | ||||
| 				}, | ||||
| 			} | ||||
| 			var gwData []byte | ||||
| 			if nh.Gw != nil { | ||||
| 				gwFamily := nl.GetIPFamily(nh.Gw) | ||||
| 				if family != -1 && family != gwFamily { | ||||
| 					return fmt.Errorf("gateway, source, and destination ip are not the same IP family") | ||||
| 				} | ||||
| 				var gw *nl.RtAttr | ||||
| 				if gwFamily == FAMILY_V4 { | ||||
| 					gw = nl.NewRtAttr(syscall.RTA_GATEWAY, []byte(nh.Gw.To4())) | ||||
| 				} else { | ||||
| 					gw = nl.NewRtAttr(syscall.RTA_GATEWAY, []byte(nh.Gw.To16())) | ||||
| 				} | ||||
| 				gwData := gw.Serialize() | ||||
| 				rtnh.Len += uint16(len(gwData)) | ||||
| 			} | ||||
| 			buf = append(buf, rtnh.Serialize()...) | ||||
| 			buf = append(buf, gwData...) | ||||
| 		} | ||||
| 		rtAttrs = append(rtAttrs, nl.NewRtAttr(syscall.RTA_MULTIPATH, buf)) | ||||
| 	} | ||||
| 
 | ||||
| 	if route.Table > 0 { | ||||
| 		if route.Table >= 256 { | ||||
| 			msg.Table = syscall.RT_TABLE_UNSPEC | ||||
|  | @ -275,6 +334,40 @@ func deserializeRoute(m []byte) (Route, error) { | |||
| 			route.Priority = int(native.Uint32(attr.Value[0:4])) | ||||
| 		case syscall.RTA_TABLE: | ||||
| 			route.Table = int(native.Uint32(attr.Value[0:4])) | ||||
| 		case syscall.RTA_MULTIPATH: | ||||
| 			parseRtNexthop := func(value []byte) (*NexthopInfo, []byte, error) { | ||||
| 				if len(value) < syscall.SizeofRtNexthop { | ||||
| 					return nil, nil, fmt.Errorf("Lack of bytes") | ||||
| 				} | ||||
| 				nh := nl.DeserializeRtNexthop(value) | ||||
| 				if len(value) < int(nh.RtNexthop.Len) { | ||||
| 					return nil, nil, fmt.Errorf("Lack of bytes") | ||||
| 				} | ||||
| 				info := &NexthopInfo{ | ||||
| 					LinkIndex: int(nh.RtNexthop.Ifindex), | ||||
| 					Hops:      int(nh.RtNexthop.Hops), | ||||
| 				} | ||||
| 				attrs, err := nl.ParseRouteAttr(value[syscall.SizeofRtNexthop:int(nh.RtNexthop.Len)]) | ||||
| 				if err != nil { | ||||
| 					return nil, nil, err | ||||
| 				} | ||||
| 				for _, attr := range attrs { | ||||
| 					switch attr.Attr.Type { | ||||
| 					case syscall.RTA_GATEWAY: | ||||
| 						info.Gw = net.IP(attr.Value) | ||||
| 					} | ||||
| 				} | ||||
| 				return info, value[int(nh.RtNexthop.Len):], nil | ||||
| 			} | ||||
| 			rest := attr.Value | ||||
| 			for len(rest) > 0 { | ||||
| 				info, buf, err := parseRtNexthop(rest) | ||||
| 				if err != nil { | ||||
| 					return route, err | ||||
| 				} | ||||
| 				route.MultiPath = append(route.MultiPath, info) | ||||
| 				rest = buf | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
| 	return route, nil | ||||
|  |  | |||
|  | @ -0,0 +1,7 @@ | |||
| // +build !linux
 | ||||
| 
 | ||||
| package netlink | ||||
| 
 | ||||
| func (r *Route) ListFlags() []string { | ||||
| 	return []string{} | ||||
| } | ||||
|  | @ -3,13 +3,10 @@ package netlink | |||
| import ( | ||||
| 	"fmt" | ||||
| 	"net" | ||||
| 
 | ||||
| 	"github.com/vishvananda/netlink/nl" | ||||
| ) | ||||
| 
 | ||||
| // Rule represents a netlink rule.
 | ||||
| type Rule struct { | ||||
| 	*nl.RtMsg | ||||
| 	Priority          int | ||||
| 	Table             int | ||||
| 	Mark              int | ||||
|  |  | |||
|  | @ -165,7 +165,6 @@ func (h *Handle) RuleList(family int) ([]Rule, error) { | |||
| 		} | ||||
| 
 | ||||
| 		rule := NewRule() | ||||
| 		rule.RtMsg = msg | ||||
| 
 | ||||
| 		for j := range attrs { | ||||
| 			switch attrs[j].Attr.Type { | ||||
|  |  | |||
|  | @ -13,7 +13,7 @@ const ( | |||
| 	XFRM_PROTO_ESP       Proto = syscall.IPPROTO_ESP | ||||
| 	XFRM_PROTO_AH        Proto = syscall.IPPROTO_AH | ||||
| 	XFRM_PROTO_HAO       Proto = syscall.IPPROTO_DSTOPTS | ||||
| 	XFRM_PROTO_COMP      Proto = syscall.IPPROTO_COMP | ||||
| 	XFRM_PROTO_COMP      Proto = 0x6c // NOTE not defined on darwin
 | ||||
| 	XFRM_PROTO_IPSEC_ANY Proto = syscall.IPPROTO_RAW | ||||
| ) | ||||
| 
 | ||||
|  |  | |||
|  | @ -3,8 +3,6 @@ package netlink | |||
| import ( | ||||
| 	"fmt" | ||||
| 	"net" | ||||
| 
 | ||||
| 	"github.com/vishvananda/netlink/nl" | ||||
| ) | ||||
| 
 | ||||
| // XfrmStateAlgo represents the algorithm to use for the ipsec encryption.
 | ||||
|  | @ -93,7 +91,7 @@ func (sa XfrmState) Print(stats bool) string { | |||
| } | ||||
| 
 | ||||
| func printLimit(lmt uint64) string { | ||||
| 	if lmt == nl.XFRM_INF { | ||||
| 	if lmt == ^uint64(0) { | ||||
| 		return "(INF)" | ||||
| 	} | ||||
| 	return fmt.Sprintf("%d", lmt) | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue