Update to current master, to get IPVLAN L3s def.
{
"ImportPath": "github.com/containernetworking/cni",
"GoVersion": "go1.6",
- "GodepVersion": "v74",
+ "GodepVersion": "v75",
"Packages": [
"./..."
],
},
{
"ImportPath": "github.com/vishvananda/netlink",
- "Rev": "9dee363ad4abbc3c9a4a24a9f1e33363e224b111"
+ "Rev": "a1f8555521646b5a9800f39c5fd477597697135c"
},
{
"ImportPath": "github.com/vishvananda/netlink/nl",
- "Rev": "9dee363ad4abbc3c9a4a24a9f1e33363e224b111"
+ "Rev": "a1f8555521646b5a9800f39c5fd477597697135c"
},
{
"ImportPath": "golang.org/x/sys/unix",
#include <stdint.h>
#include <unistd.h>
-static int load_simple_bpf(int prog_type) {
+static int load_simple_bpf(int prog_type, int ret) {
#ifdef __NR_bpf
- // { return 1; }
+ // { return ret; }
__u64 __attribute__((aligned(8))) insns[] = {
- 0x00000001000000b7ull,
+ 0x00000000000000b7ull | ((__u64)ret<<32),
0x0000000000000095ull,
};
__u8 __attribute__((aligned(8))) license[] = "ASL2";
BPF_PROG_TYPE_KPROBE
BPF_PROG_TYPE_SCHED_CLS
BPF_PROG_TYPE_SCHED_ACT
+ BPF_PROG_TYPE_TRACEPOINT
+ BPF_PROG_TYPE_XDP
)
// loadSimpleBpf loads a trivial bpf program for testing purposes
-func loadSimpleBpf(progType BpfProgType) (int, error) {
- fd, err := C.load_simple_bpf(C.int(progType))
+func loadSimpleBpf(progType BpfProgType, ret int) (int, error) {
+ fd, err := C.load_simple_bpf(C.int(progType), C.int(ret))
return int(fd), err
}
case TC_ACT_JUMP:
return "jump"
}
- return fmt.Sprintf("0x%x", a)
+ return fmt.Sprintf("0x%x", int32(a))
}
type TcPolAct int32
case TC_POLICE_PIPE:
return "pipe"
}
- return fmt.Sprintf("0x%x", a)
+ return fmt.Sprintf("0x%x", int32(a))
}
type ActionAttrs struct {
Name string
HardwareAddr net.HardwareAddr
Flags net.Flags
+ RawFlags uint32
ParentIndex int // index of the parent link device
MasterIndex int // must be the index of a bridge
Namespace interface{} // nil | NsPid | NsFd
Alias string
Statistics *LinkStatistics
+ Promisc int
+ Xdp *LinkXdp
+ EncapType string
}
// NewLinkAttrs returns LinkAttrs structure filled with default values
TxCompressed uint32
}
+type LinkXdp struct {
+ Fd int
+ Attached bool
+}
+
// Device links cannot be created via netlink. These links
// are links created by udev like 'lo' and 'etho0'
type Device struct {
const (
IPVLAN_MODE_L2 IPVlanMode = iota
IPVLAN_MODE_L3
+ IPVLAN_MODE_L3S
IPVLAN_MODE_MAX
)
}
}
+func (h *Handle) SetPromiscOn(link Link) error {
+ base := link.Attrs()
+ h.ensureIndex(base)
+ req := h.newNetlinkRequest(syscall.RTM_SETLINK, syscall.NLM_F_ACK)
+
+ msg := nl.NewIfInfomsg(syscall.AF_UNSPEC)
+ msg.Change = syscall.IFF_PROMISC
+ msg.Flags = syscall.IFF_UP
+ msg.Index = int32(base.Index)
+ req.AddData(msg)
+
+ _, err := req.Execute(syscall.NETLINK_ROUTE, 0)
+ return err
+}
+
+func SetPromiscOn(link Link) error {
+ return pkgHandle.SetPromiscOn(link)
+}
+
+func (h *Handle) SetPromiscOff(link Link) error {
+ base := link.Attrs()
+ h.ensureIndex(base)
+ req := h.newNetlinkRequest(syscall.RTM_SETLINK, syscall.NLM_F_ACK)
+
+ msg := nl.NewIfInfomsg(syscall.AF_UNSPEC)
+ msg.Change = syscall.IFF_PROMISC
+ msg.Flags = 0 & ^syscall.IFF_UP
+ msg.Index = int32(base.Index)
+ req.AddData(msg)
+
+ _, err := req.Execute(syscall.NETLINK_ROUTE, 0)
+ return err
+}
+
+func SetPromiscOff(link Link) error {
+ return pkgHandle.SetPromiscOff(link)
+}
+
// LinkSetUp enables the link device.
// Equivalent to: `ip link set $link up`
func LinkSetUp(link Link) error {
return err
}
+// LinkSetXdpFd adds a bpf function to the driver. The fd must be a bpf
+// program loaded with bpf(type=BPF_PROG_TYPE_XDP)
+func LinkSetXdpFd(link Link, fd int) error {
+ base := link.Attrs()
+ ensureIndex(base)
+ req := nl.NewNetlinkRequest(syscall.RTM_SETLINK, syscall.NLM_F_ACK)
+
+ msg := nl.NewIfInfomsg(syscall.AF_UNSPEC)
+ msg.Index = int32(base.Index)
+ req.AddData(msg)
+
+ addXdpAttrs(&LinkXdp{Fd: fd}, req)
+
+ _, err := req.Execute(syscall.NETLINK_ROUTE, 0)
+ return err
+}
+
func boolAttr(val bool) []byte {
var v uint8
if val {
req.AddData(attr)
}
+ if base.Xdp != nil {
+ addXdpAttrs(base.Xdp, req)
+ }
+
linkInfo := nl.NewRtAttr(syscall.IFLA_LINKINFO, nil)
nl.NewRtAttrChild(linkInfo, nl.IFLA_INFO_KIND, nl.NonZeroTerminated(link.Type()))
return nil, err
}
- base := LinkAttrs{Index: int(msg.Index), Flags: linkFlags(msg.Flags)}
+ base := LinkAttrs{Index: int(msg.Index), RawFlags: msg.Flags, Flags: linkFlags(msg.Flags), EncapType: msg.EncapType()}
+ if msg.Flags&syscall.IFF_PROMISC != 0 {
+ base.Promisc = 1
+ }
var link Link
linkType := ""
for _, attr := range attrs {
base.Alias = string(attr.Value[:len(attr.Value)-1])
case syscall.IFLA_STATS:
base.Statistics = parseLinkStats(attr.Value[:])
+ case nl.IFLA_XDP:
+ xdp, err := parseLinkXdp(attr.Value[:])
+ if err != nil {
+ return nil, err
+ }
+ base.Xdp = xdp
}
}
// Links that don't have IFLA_INFO_KIND are hardware devices
func parseLinkStats(data []byte) *LinkStatistics {
return (*LinkStatistics)(unsafe.Pointer(&data[0:SizeofLinkStats][0]))
}
+
+func addXdpAttrs(xdp *LinkXdp, req *nl.NetlinkRequest) {
+ attrs := nl.NewRtAttr(nl.IFLA_XDP|syscall.NLA_F_NESTED, nil)
+ b := make([]byte, 4)
+ native.PutUint32(b, uint32(xdp.Fd))
+ nl.NewRtAttrChild(attrs, nl.IFLA_XDP_FD, b)
+ req.AddData(attrs)
+}
+
+func parseLinkXdp(data []byte) (*LinkXdp, error) {
+ attrs, err := nl.ParseRouteAttr(data)
+ if err != nil {
+ return nil, err
+ }
+ xdp := &LinkXdp{}
+ for _, attr := range attrs {
+ switch attr.Attr.Type {
+ case nl.IFLA_XDP_FD:
+ xdp.Fd = int(native.Uint32(attr.Value[0:4]))
+ case nl.IFLA_XDP_ATTACHED:
+ xdp.Attached = attr.Value[0] != 0
+ }
+ }
+ return xdp, nil
+}
dstData := nl.NewRtAttr(NDA_DST, ipData)
req.AddData(dstData)
- hwData := nl.NewRtAttr(NDA_LLADDR, []byte(neigh.HardwareAddr))
- req.AddData(hwData)
+ if neigh.Flags != NTF_PROXY || neigh.HardwareAddr != nil {
+ hwData := nl.NewRtAttr(NDA_LLADDR, []byte(neigh.HardwareAddr))
+ req.AddData(hwData)
+ }
_, err := req.Execute(syscall.NETLINK_ROUTE, 0)
return err
return pkgHandle.NeighList(linkIndex, family)
}
+// NeighProxyList gets a list of neighbor proxies in the system.
+// Equivalent to: `ip neighbor show proxy`.
+// The list can be filtered by link and ip family.
+func NeighProxyList(linkIndex, family int) ([]Neigh, error) {
+ return pkgHandle.NeighProxyList(linkIndex, family)
+}
+
// NeighList gets a list of IP-MAC mappings in the system (ARP table).
// Equivalent to: `ip neighbor show`.
// The list can be filtered by link and ip family.
func (h *Handle) NeighList(linkIndex, family int) ([]Neigh, error) {
+ return h.neighList(linkIndex, family, 0)
+}
+
+// NeighProxyList gets a list of neighbor proxies in the system.
+// Equivalent to: `ip neighbor show proxy`.
+// The list can be filtered by link, ip family.
+func (h *Handle) NeighProxyList(linkIndex, family int) ([]Neigh, error) {
+ return h.neighList(linkIndex, family, NTF_PROXY)
+}
+
+func (h *Handle) neighList(linkIndex, family, flags int) ([]Neigh, error) {
req := h.newNetlinkRequest(syscall.RTM_GETNEIGH, syscall.NLM_F_DUMP)
msg := Ndmsg{
Family: uint8(family),
Index: uint32(linkIndex),
+ Flags: uint8(flags),
}
req.AddData(&msg)
package nl
import (
+ "syscall"
"unsafe"
)
const (
DEFAULT_CHANGE = 0xFFFFFFFF
// doesn't exist in syscall
- IFLA_VFINFO_LIST = 0x16
+ IFLA_VFINFO_LIST = syscall.IFLA_IFALIAS + 1 + iota
+ IFLA_STATS64
+ IFLA_VF_PORTS
+ IFLA_PORT_SELF
+ IFLA_AF_SPEC
+ IFLA_GROUP
+ IFLA_NET_NS_FD
+ IFLA_EXT_MASK
+ IFLA_PROMISCUITY
+ IFLA_NUM_TX_QUEUES
+ IFLA_NUM_RX_QUEUES
+ IFLA_CARRIER
+ IFLA_PHYS_PORT_ID
+ IFLA_CARRIER_CHANGES
+ IFLA_PHYS_SWITCH_ID
+ IFLA_LINK_NETNSID
+ IFLA_PHYS_PORT_NAME
+ IFLA_PROTO_DOWN
+ IFLA_GSO_MAX_SEGS
+ IFLA_GSO_MAX_SIZE
+ IFLA_PAD
+ IFLA_XDP
)
const (
IFLA_IPVLAN_MAX = IFLA_IPVLAN_MODE
)
-const (
- // not defined in syscall
- IFLA_NET_NS_FD = 28
-)
-
const (
IFLA_MACVLAN_UNSPEC = iota
IFLA_MACVLAN_MODE
func (msg *VfRssQueryEn) Serialize() []byte {
return (*(*[SizeofVfRssQueryEn]byte)(unsafe.Pointer(msg)))[:]
}
+
+const (
+ IFLA_XDP_UNSPEC = iota
+ IFLA_XDP_FD /* fd of xdp program to attach, or -1 to remove */
+ IFLA_XDP_ATTACHED /* read-only bool indicating if prog is attached */
+ IFLA_XDP_MAX = IFLA_XDP_ATTACHED
+)
return syscall.SizeofIfInfomsg
}
+func (msg *IfInfomsg) EncapType() string {
+ switch msg.Type {
+ case 0:
+ return "generic"
+ case syscall.ARPHRD_ETHER:
+ return "ether"
+ case syscall.ARPHRD_EETHER:
+ return "eether"
+ case syscall.ARPHRD_AX25:
+ return "ax25"
+ case syscall.ARPHRD_PRONET:
+ return "pronet"
+ case syscall.ARPHRD_CHAOS:
+ return "chaos"
+ case syscall.ARPHRD_IEEE802:
+ return "ieee802"
+ case syscall.ARPHRD_ARCNET:
+ return "arcnet"
+ case syscall.ARPHRD_APPLETLK:
+ return "atalk"
+ case syscall.ARPHRD_DLCI:
+ return "dlci"
+ case syscall.ARPHRD_ATM:
+ return "atm"
+ case syscall.ARPHRD_METRICOM:
+ return "metricom"
+ case syscall.ARPHRD_IEEE1394:
+ return "ieee1394"
+ case syscall.ARPHRD_INFINIBAND:
+ return "infiniband"
+ case syscall.ARPHRD_SLIP:
+ return "slip"
+ case syscall.ARPHRD_CSLIP:
+ return "cslip"
+ case syscall.ARPHRD_SLIP6:
+ return "slip6"
+ case syscall.ARPHRD_CSLIP6:
+ return "cslip6"
+ case syscall.ARPHRD_RSRVD:
+ return "rsrvd"
+ case syscall.ARPHRD_ADAPT:
+ return "adapt"
+ case syscall.ARPHRD_ROSE:
+ return "rose"
+ case syscall.ARPHRD_X25:
+ return "x25"
+ case syscall.ARPHRD_HWX25:
+ return "hwx25"
+ case syscall.ARPHRD_PPP:
+ return "ppp"
+ case syscall.ARPHRD_HDLC:
+ return "hdlc"
+ case syscall.ARPHRD_LAPB:
+ return "lapb"
+ case syscall.ARPHRD_DDCMP:
+ return "ddcmp"
+ case syscall.ARPHRD_RAWHDLC:
+ return "rawhdlc"
+ case syscall.ARPHRD_TUNNEL:
+ return "ipip"
+ case syscall.ARPHRD_TUNNEL6:
+ return "tunnel6"
+ case syscall.ARPHRD_FRAD:
+ return "frad"
+ case syscall.ARPHRD_SKIP:
+ return "skip"
+ case syscall.ARPHRD_LOOPBACK:
+ return "loopback"
+ case syscall.ARPHRD_LOCALTLK:
+ return "ltalk"
+ case syscall.ARPHRD_FDDI:
+ return "fddi"
+ case syscall.ARPHRD_BIF:
+ return "bif"
+ case syscall.ARPHRD_SIT:
+ return "sit"
+ case syscall.ARPHRD_IPDDP:
+ return "ip/ddp"
+ case syscall.ARPHRD_IPGRE:
+ return "gre"
+ case syscall.ARPHRD_PIMREG:
+ return "pimreg"
+ case syscall.ARPHRD_HIPPI:
+ return "hippi"
+ case syscall.ARPHRD_ASH:
+ return "ash"
+ case syscall.ARPHRD_ECONET:
+ return "econet"
+ case syscall.ARPHRD_IRDA:
+ return "irda"
+ case syscall.ARPHRD_FCPP:
+ return "fcpp"
+ case syscall.ARPHRD_FCAL:
+ return "fcal"
+ case syscall.ARPHRD_FCPL:
+ return "fcpl"
+ case syscall.ARPHRD_FCFABRIC:
+ return "fcfb0"
+ case syscall.ARPHRD_FCFABRIC + 1:
+ return "fcfb1"
+ case syscall.ARPHRD_FCFABRIC + 2:
+ return "fcfb2"
+ case syscall.ARPHRD_FCFABRIC + 3:
+ return "fcfb3"
+ case syscall.ARPHRD_FCFABRIC + 4:
+ return "fcfb4"
+ case syscall.ARPHRD_FCFABRIC + 5:
+ return "fcfb5"
+ case syscall.ARPHRD_FCFABRIC + 6:
+ return "fcfb6"
+ case syscall.ARPHRD_FCFABRIC + 7:
+ return "fcfb7"
+ case syscall.ARPHRD_FCFABRIC + 8:
+ return "fcfb8"
+ case syscall.ARPHRD_FCFABRIC + 9:
+ return "fcfb9"
+ case syscall.ARPHRD_FCFABRIC + 10:
+ return "fcfb10"
+ case syscall.ARPHRD_FCFABRIC + 11:
+ return "fcfb11"
+ case syscall.ARPHRD_FCFABRIC + 12:
+ return "fcfb12"
+ case syscall.ARPHRD_IEEE802_TR:
+ return "tr"
+ case syscall.ARPHRD_IEEE80211:
+ return "ieee802.11"
+ case syscall.ARPHRD_IEEE80211_PRISM:
+ return "ieee802.11/prism"
+ case syscall.ARPHRD_IEEE80211_RADIOTAP:
+ return "ieee802.11/radiotap"
+ case syscall.ARPHRD_IEEE802154:
+ return "ieee802.15.4"
+
+ case 65534:
+ return "none"
+ case 65535:
+ return "void"
+ }
+ return fmt.Sprintf("unknown%d", msg.Type)
+}
+
func rtaAlignOf(attrlen int) int {
return (attrlen + syscall.RTA_ALIGNTO - 1) & ^(syscall.RTA_ALIGNTO - 1)
}
} else {
gw = nl.NewRtAttr(syscall.RTA_GATEWAY, []byte(nh.Gw.To16()))
}
- gwData := gw.Serialize()
+ gwData = gw.Serialize()
rtnh.Len += uint16(len(gwData))
}
buf = append(buf, rtnh.Serialize()...)
req.AddData(rtAttrs[i])
}
- var (
- b = make([]byte, 4)
- native = nl.NativeEndian()
- )
+ native := nl.NativeEndian()
if rule.Priority >= 0 {
+ b := make([]byte, 4)
native.PutUint32(b, uint32(rule.Priority))
req.AddData(nl.NewRtAttr(nl.FRA_PRIORITY, b))
}
if rule.Mark >= 0 {
+ b := make([]byte, 4)
native.PutUint32(b, uint32(rule.Mark))
req.AddData(nl.NewRtAttr(nl.FRA_FWMARK, b))
}
if rule.Mask >= 0 {
+ b := make([]byte, 4)
native.PutUint32(b, uint32(rule.Mask))
req.AddData(nl.NewRtAttr(nl.FRA_FWMASK, b))
}
if rule.Flow >= 0 {
+ b := make([]byte, 4)
native.PutUint32(b, uint32(rule.Flow))
req.AddData(nl.NewRtAttr(nl.FRA_FLOW, b))
}
if rule.TunID > 0 {
+ b := make([]byte, 4)
native.PutUint32(b, uint32(rule.TunID))
req.AddData(nl.NewRtAttr(nl.FRA_TUN_ID, b))
}
if rule.Table >= 256 {
+ b := make([]byte, 4)
native.PutUint32(b, uint32(rule.Table))
req.AddData(nl.NewRtAttr(nl.FRA_TABLE, b))
}
if msg.Table > 0 {
if rule.SuppressPrefixlen >= 0 {
+ b := make([]byte, 4)
native.PutUint32(b, uint32(rule.SuppressPrefixlen))
req.AddData(nl.NewRtAttr(nl.FRA_SUPPRESS_PREFIXLEN, b))
}
if rule.SuppressIfgroup >= 0 {
+ b := make([]byte, 4)
native.PutUint32(b, uint32(rule.SuppressIfgroup))
req.AddData(nl.NewRtAttr(nl.FRA_SUPPRESS_IFGROUP, b))
}
}
if rule.Goto >= 0 {
msg.Type = nl.FR_ACT_NOP
+ b := make([]byte, 4)
native.PutUint32(b, uint32(rule.Goto))
req.AddData(nl.NewRtAttr(nl.FRA_GOTO, b))
}