From 1607b4be6fd10ac982007a3e8bb51c0e782904bd Mon Sep 17 00:00:00 2001 From: Alessandro Boch Date: Tue, 31 May 2016 14:20:46 -0700 Subject: [PATCH] Update netlink to 7995ff5 Signed-off-by: Alessandro Boch --- libnetwork/Godeps/Godeps.json | 4 +- .../github.com/vishvananda/netlink/filter.go | 145 ++++++++++++++- .../vishvananda/netlink/filter_linux.go | 54 +++++- .../vishvananda/netlink/nl/nl_linux.go | 7 + .../vishvananda/netlink/nl/tc_linux.go | 165 ++++++++---------- .../vishvananda/netlink/xfrm_policy.go | 5 +- .../vishvananda/netlink/xfrm_policy_linux.go | 10 +- 7 files changed, 283 insertions(+), 107 deletions(-) diff --git a/libnetwork/Godeps/Godeps.json b/libnetwork/Godeps/Godeps.json index 7bb4f7b1c9..8d234c1297 100644 --- a/libnetwork/Godeps/Godeps.json +++ b/libnetwork/Godeps/Godeps.json @@ -398,11 +398,11 @@ }, { "ImportPath": "github.com/vishvananda/netlink", - "Rev": "b824519a9a33e5a757ba599209d66a34be8361b1" + "Rev": "7995ff5647a22cbf0dc41bf5c0e977bdb0d5c6b7" }, { "ImportPath": "github.com/vishvananda/netlink/nl", - "Rev": "b824519a9a33e5a757ba599209d66a34be8361b1" + "Rev": "7995ff5647a22cbf0dc41bf5c0e977bdb0d5c6b7" }, { "ImportPath": "github.com/vishvananda/netns", diff --git a/libnetwork/Godeps/_workspace/src/github.com/vishvananda/netlink/filter.go b/libnetwork/Godeps/_workspace/src/github.com/vishvananda/netlink/filter.go index 8d62ca55ef..7e178ee00a 100644 --- a/libnetwork/Godeps/_workspace/src/github.com/vishvananda/netlink/filter.go +++ b/libnetwork/Godeps/_workspace/src/github.com/vishvananda/netlink/filter.go @@ -3,6 +3,7 @@ package netlink import ( "errors" "fmt" + "github.com/vishvananda/netlink/nl" ) @@ -26,13 +27,105 @@ 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) } +type TcAct int32 + +const ( + TC_ACT_UNSPEC TcAct = -1 + TC_ACT_OK TcAct = 0 + TC_ACT_RECLASSIFY TcAct = 1 + TC_ACT_SHOT TcAct = 2 + TC_ACT_PIPE TcAct = 3 + TC_ACT_STOLEN TcAct = 4 + TC_ACT_QUEUED TcAct = 5 + TC_ACT_REPEAT TcAct = 6 + TC_ACT_REDIRECT TcAct = 7 + TC_ACT_JUMP TcAct = 0x10000000 +) + +func (a TcAct) String() string { + switch a { + case TC_ACT_UNSPEC: + return "unspec" + case TC_ACT_OK: + return "ok" + case TC_ACT_RECLASSIFY: + return "reclassify" + case TC_ACT_SHOT: + return "shot" + case TC_ACT_PIPE: + return "pipe" + case TC_ACT_STOLEN: + return "stolen" + case TC_ACT_QUEUED: + return "queued" + case TC_ACT_REPEAT: + return "repeat" + case TC_ACT_REDIRECT: + return "redirect" + case TC_ACT_JUMP: + return "jump" + } + return fmt.Sprintf("0x%x", a) +} + +type TcPolAct int32 + +const ( + TC_POLICE_UNSPEC TcPolAct = TcPolAct(TC_ACT_UNSPEC) + TC_POLICE_OK TcPolAct = TcPolAct(TC_ACT_OK) + TC_POLICE_RECLASSIFY TcPolAct = TcPolAct(TC_ACT_RECLASSIFY) + TC_POLICE_SHOT TcPolAct = TcPolAct(TC_ACT_SHOT) + TC_POLICE_PIPE TcPolAct = TcPolAct(TC_ACT_PIPE) +) + +func (a TcPolAct) String() string { + switch a { + case TC_POLICE_UNSPEC: + return "unspec" + case TC_POLICE_OK: + return "ok" + case TC_POLICE_RECLASSIFY: + return "reclassify" + case TC_POLICE_SHOT: + return "shot" + case TC_POLICE_PIPE: + return "pipe" + } + return fmt.Sprintf("0x%x", a) +} + +type ActionAttrs struct { + Index int + Capab int + Action TcAct + Refcnt int + Bindcnt int +} + +func (q ActionAttrs) String() string { + return fmt.Sprintf("{Index: %d, Capab: %x, Action: %s, Refcnt: %d, Bindcnt: %d}", q.Index, q.Capab, q.Action.String(), q.Refcnt, q.Bindcnt) +} + // Action represents an action in any supported filter. type Action interface { + Attrs() *ActionAttrs Type() string } +type GenericAction struct { + ActionAttrs +} + +func (action *GenericAction) Type() string { + return "generic" +} + +func (action *GenericAction) Attrs() *ActionAttrs { + return &action.ActionAttrs +} + type BpfAction struct { - nl.TcActBpf + ActionAttrs Fd int Name string } @@ -41,21 +134,54 @@ func (action *BpfAction) Type() string { return "bpf" } +func (action *BpfAction) Attrs() *ActionAttrs { + return &action.ActionAttrs +} + +type MirredAct uint8 + +func (a MirredAct) String() string { + switch a { + case TCA_EGRESS_REDIR: + return "egress redir" + case TCA_EGRESS_MIRROR: + return "egress mirror" + case TCA_INGRESS_REDIR: + return "ingress redir" + case TCA_INGRESS_MIRROR: + return "ingress mirror" + } + return "unknown" +} + +const ( + TCA_EGRESS_REDIR MirredAct = 1 /* packet redirect to EGRESS*/ + TCA_EGRESS_MIRROR MirredAct = 2 /* mirror packet to EGRESS */ + TCA_INGRESS_REDIR MirredAct = 3 /* packet redirect to INGRESS*/ + TCA_INGRESS_MIRROR MirredAct = 4 /* mirror packet to INGRESS */ +) + type MirredAction struct { - nl.TcMirred + ActionAttrs + MirredAction MirredAct + Ifindex int } func (action *MirredAction) Type() string { return "mirred" } +func (action *MirredAction) Attrs() *ActionAttrs { + return &action.ActionAttrs +} + func NewMirredAction(redirIndex int) *MirredAction { return &MirredAction{ - TcMirred: nl.TcMirred{ - TcGen: nl.TcGen{Action: nl.TC_ACT_STOLEN}, - Eaction: nl.TCA_EGRESS_REDIR, - Ifindex: uint32(redirIndex), + ActionAttrs: ActionAttrs{ + Action: TC_ACT_STOLEN, }, + MirredAction: TCA_EGRESS_REDIR, + Ifindex: redirIndex, } } @@ -86,7 +212,7 @@ type FilterFwAttrs struct { Rate uint32 AvRate uint32 PeakRate uint32 - Action int + Action TcPolAct Overhead uint16 LinkLayer int } @@ -95,8 +221,9 @@ type FilterFwAttrs struct { type Fw struct { FilterAttrs ClassId uint32 - Police nl.TcPolice - InDev string + // TODO remove nl type from interface + Police nl.TcPolice + InDev string // TODO Action Mask uint32 AvRate uint32 diff --git a/libnetwork/Godeps/_workspace/src/github.com/vishvananda/netlink/filter_linux.go b/libnetwork/Godeps/_workspace/src/github.com/vishvananda/netlink/filter_linux.go index cf1e13d965..2a8cf89022 100644 --- a/libnetwork/Godeps/_workspace/src/github.com/vishvananda/netlink/filter_linux.go +++ b/libnetwork/Godeps/_workspace/src/github.com/vishvananda/netlink/filter_linux.go @@ -207,6 +207,8 @@ func (h *Handle) FilterList(link Link, parent uint32) ([]Filter, error) { if err != nil { return nil, err } + default: + detailed = true } } } @@ -220,6 +222,22 @@ func (h *Handle) FilterList(link Link, parent uint32) ([]Filter, error) { return res, nil } +func toTcGen(attrs *ActionAttrs, tcgen *nl.TcGen) { + tcgen.Index = uint32(attrs.Index) + tcgen.Capab = uint32(attrs.Capab) + tcgen.Action = int32(attrs.Action) + tcgen.Refcnt = int32(attrs.Refcnt) + tcgen.Bindcnt = int32(attrs.Bindcnt) +} + +func toAttrs(tcgen *nl.TcGen, attrs *ActionAttrs) { + attrs.Index = int(tcgen.Index) + attrs.Capab = int(tcgen.Capab) + attrs.Action = TcAct(tcgen.Action) + attrs.Refcnt = int(tcgen.Refcnt) + attrs.Bindcnt = int(tcgen.Bindcnt) +} + func encodeActions(attr *nl.RtAttr, actions []Action) error { tabIndex := int(nl.TCA_ACT_TAB) @@ -232,15 +250,30 @@ func encodeActions(attr *nl.RtAttr, actions []Action) error { tabIndex++ nl.NewRtAttrChild(table, nl.TCA_ACT_KIND, nl.ZeroTerminated("mirred")) aopts := nl.NewRtAttrChild(table, nl.TCA_ACT_OPTIONS, nil) - nl.NewRtAttrChild(aopts, nl.TCA_MIRRED_PARMS, action.Serialize()) + mirred := nl.TcMirred{ + Eaction: int32(action.MirredAction), + Ifindex: uint32(action.Ifindex), + } + toTcGen(action.Attrs(), &mirred.TcGen) + nl.NewRtAttrChild(aopts, nl.TCA_MIRRED_PARMS, mirred.Serialize()) case *BpfAction: table := nl.NewRtAttrChild(attr, tabIndex, nil) tabIndex++ nl.NewRtAttrChild(table, nl.TCA_ACT_KIND, nl.ZeroTerminated("bpf")) aopts := nl.NewRtAttrChild(table, nl.TCA_ACT_OPTIONS, nil) - nl.NewRtAttrChild(aopts, nl.TCA_ACT_BPF_PARMS, action.Serialize()) + gen := nl.TcGen{} + toTcGen(action.Attrs(), &gen) + nl.NewRtAttrChild(aopts, nl.TCA_ACT_BPF_PARMS, gen.Serialize()) nl.NewRtAttrChild(aopts, nl.TCA_ACT_BPF_FD, nl.Uint32Attr(uint32(action.Fd))) nl.NewRtAttrChild(aopts, nl.TCA_ACT_BPF_NAME, nl.ZeroTerminated(action.Name)) + case *GenericAction: + table := nl.NewRtAttrChild(attr, tabIndex, nil) + tabIndex++ + nl.NewRtAttrChild(table, nl.TCA_ACT_KIND, nl.ZeroTerminated("gact")) + aopts := nl.NewRtAttrChild(table, nl.TCA_ACT_OPTIONS, nil) + gen := nl.TcGen{} + toTcGen(action.Attrs(), &gen) + nl.NewRtAttrChild(aopts, nl.TCA_GACT_PARMS, gen.Serialize()) } } return nil @@ -266,6 +299,8 @@ func parseActions(tables []syscall.NetlinkRouteAttr) ([]Action, error) { action = &MirredAction{} case "bpf": action = &BpfAction{} + case "gact": + action = &GenericAction{} default: break nextattr } @@ -279,17 +314,28 @@ func parseActions(tables []syscall.NetlinkRouteAttr) ([]Action, error) { case "mirred": switch adatum.Attr.Type { case nl.TCA_MIRRED_PARMS: - action.(*MirredAction).TcMirred = *nl.DeserializeTcMirred(adatum.Value) + mirred := *nl.DeserializeTcMirred(adatum.Value) + toAttrs(&mirred.TcGen, action.Attrs()) + action.(*MirredAction).ActionAttrs = ActionAttrs{} + action.(*MirredAction).Ifindex = int(mirred.Ifindex) + action.(*MirredAction).MirredAction = MirredAct(mirred.Eaction) } case "bpf": switch adatum.Attr.Type { case nl.TCA_ACT_BPF_PARMS: - action.(*BpfAction).TcActBpf = *nl.DeserializeTcActBpf(adatum.Value) + gen := *nl.DeserializeTcGen(adatum.Value) + toAttrs(&gen, action.Attrs()) case nl.TCA_ACT_BPF_FD: action.(*BpfAction).Fd = int(native.Uint32(adatum.Value[0:4])) case nl.TCA_ACT_BPF_NAME: action.(*BpfAction).Name = string(adatum.Value[:len(adatum.Value)-1]) } + case "gact": + switch adatum.Attr.Type { + case nl.TCA_GACT_PARMS: + gen := *nl.DeserializeTcGen(adatum.Value) + toAttrs(&gen, action.Attrs()) + } } } } diff --git a/libnetwork/Godeps/_workspace/src/github.com/vishvananda/netlink/nl/nl_linux.go b/libnetwork/Godeps/_workspace/src/github.com/vishvananda/netlink/nl/nl_linux.go index 8306890526..f41821dd72 100644 --- a/libnetwork/Godeps/_workspace/src/github.com/vishvananda/netlink/nl/nl_linux.go +++ b/libnetwork/Godeps/_workspace/src/github.com/vishvananda/netlink/nl/nl_linux.go @@ -380,6 +380,7 @@ func Subscribe(protocol int, groups ...uint) (*NetlinkSocket, error) { func (s *NetlinkSocket) Close() { syscall.Close(s.fd) + s.fd = -1 } func (s *NetlinkSocket) GetFd() int { @@ -387,6 +388,9 @@ func (s *NetlinkSocket) GetFd() int { } func (s *NetlinkSocket) Send(request *NetlinkRequest) error { + if s.fd < 0 { + return fmt.Errorf("Send called on a closed socket") + } if err := syscall.Sendto(s.fd, request.Serialize(), 0, &s.lsa); err != nil { return err } @@ -394,6 +398,9 @@ func (s *NetlinkSocket) Send(request *NetlinkRequest) error { } func (s *NetlinkSocket) Receive() ([]syscall.NetlinkMessage, error) { + if s.fd < 0 { + return nil, fmt.Errorf("Receive called on a closed socket") + } rb := make([]byte, syscall.Getpagesize()) nr, _, err := syscall.Recvfrom(s.fd, rb, 0) if err != nil { diff --git a/libnetwork/Godeps/_workspace/src/github.com/vishvananda/netlink/nl/tc_linux.go b/libnetwork/Godeps/_workspace/src/github.com/vishvananda/netlink/nl/tc_linux.go index c6d85e951d..e91fb21c55 100644 --- a/libnetwork/Godeps/_workspace/src/github.com/vishvananda/netlink/nl/tc_linux.go +++ b/libnetwork/Godeps/_workspace/src/github.com/vishvananda/netlink/nl/tc_linux.go @@ -78,8 +78,8 @@ const ( SizeofTcHtbGlob = 0x14 SizeofTcU32Key = 0x10 SizeofTcU32Sel = 0x10 // without keys - SizeofTcActBpf = 0x14 - SizeofTcMirred = 0x1c + SizeofTcGen = 0x14 + SizeofTcMirred = SizeofTcGen + 0x08 SizeofTcPolice = 2*SizeofTcRateSpec + 0x20 ) @@ -516,6 +516,81 @@ func (x *TcU32Sel) Serialize() []byte { return buf } +type TcGen struct { + Index uint32 + Capab uint32 + Action int32 + Refcnt int32 + Bindcnt int32 +} + +func (msg *TcGen) Len() int { + return SizeofTcGen +} + +func DeserializeTcGen(b []byte) *TcGen { + return (*TcGen)(unsafe.Pointer(&b[0:SizeofTcGen][0])) +} + +func (x *TcGen) Serialize() []byte { + return (*(*[SizeofTcGen]byte)(unsafe.Pointer(x)))[:] +} + +// #define tc_gen \ +// __u32 index; \ +// __u32 capab; \ +// int action; \ +// int refcnt; \ +// int bindcnt + +const ( + TCA_ACT_GACT = 5 +) + +const ( + TCA_GACT_UNSPEC = iota + TCA_GACT_TM + TCA_GACT_PARMS + TCA_GACT_PROB + TCA_GACT_MAX = TCA_GACT_PROB +) + +type TcGact TcGen + +const ( + TCA_ACT_BPF = 13 +) + +const ( + TCA_ACT_BPF_UNSPEC = iota + TCA_ACT_BPF_TM + TCA_ACT_BPF_PARMS + TCA_ACT_BPF_OPS_LEN + TCA_ACT_BPF_OPS + TCA_ACT_BPF_FD + TCA_ACT_BPF_NAME + TCA_ACT_BPF_MAX = TCA_ACT_BPF_NAME +) + +const ( + TCA_BPF_FLAG_ACT_DIRECT uint32 = 1 << iota +) + +const ( + TCA_BPF_UNSPEC = iota + TCA_BPF_ACT + TCA_BPF_POLICE + TCA_BPF_CLASSID + TCA_BPF_OPS_LEN + TCA_BPF_OPS + TCA_BPF_FD + TCA_BPF_NAME + TCA_BPF_FLAGS + TCA_BPF_MAX = TCA_BPF_FLAGS +) + +type TcBpf TcGen + const ( TCA_ACT_MIRRED = 8 ) @@ -527,56 +602,6 @@ const ( 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_REDIRECT = 7 - TC_ACT_JUMP = 0x10000000 -) - -type TcGen struct { - Index uint32 - Capab uint32 - Action int32 - Refcnt int32 - Bindcnt int32 -} - -type TcActBpf struct { - TcGen -} - -func (msg *TcActBpf) Len() int { - return SizeofTcActBpf -} - -func DeserializeTcActBpf(b []byte) *TcActBpf { - return (*TcActBpf)(unsafe.Pointer(&b[0:SizeofTcActBpf][0])) -} - -func (x *TcActBpf) Serialize() []byte { - return (*(*[SizeofTcActBpf]byte)(unsafe.Pointer(x)))[:] -} - -// #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 */ @@ -601,14 +626,6 @@ 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; @@ -656,31 +673,3 @@ const ( TCA_FW_MASK TCA_FW_MAX = TCA_FW_MASK ) - -const ( - TCA_BPF_FLAG_ACT_DIRECT uint32 = 1 << iota -) - -const ( - TCA_BPF_UNSPEC = iota - TCA_BPF_ACT - TCA_BPF_POLICE - TCA_BPF_CLASSID - TCA_BPF_OPS_LEN - TCA_BPF_OPS - TCA_BPF_FD - TCA_BPF_NAME - TCA_BPF_FLAGS - TCA_BPF_MAX = TCA_BPF_FLAGS -) - -const ( - TCA_ACT_BPF_UNSPEC = iota - TCA_ACT_BPF_TM - TCA_ACT_BPF_PARMS - TCA_ACT_BPF_OPS_LEN - TCA_ACT_BPF_OPS - TCA_ACT_BPF_FD - TCA_ACT_BPF_NAME - TCA_ACT_BPF_MAX = TCA_ACT_BPF_NAME -) diff --git a/libnetwork/Godeps/_workspace/src/github.com/vishvananda/netlink/xfrm_policy.go b/libnetwork/Godeps/_workspace/src/github.com/vishvananda/netlink/xfrm_policy.go index 26e0edda44..c97ec43a25 100644 --- a/libnetwork/Godeps/_workspace/src/github.com/vishvananda/netlink/xfrm_policy.go +++ b/libnetwork/Godeps/_workspace/src/github.com/vishvananda/netlink/xfrm_policy.go @@ -43,12 +43,13 @@ type XfrmPolicyTmpl struct { Src net.IP Proto Proto Mode Mode + Spi int Reqid int } func (t XfrmPolicyTmpl) String() string { - return fmt.Sprintf("{Dst: %v, Src: %v, Proto: %s, Mode: %s, Reqid: 0x%x}", - t.Dst, t.Src, t.Proto, t.Mode, t.Reqid) + return fmt.Sprintf("{Dst: %v, Src: %v, Proto: %s, Mode: %s, Spi: 0x%x, Reqid: 0x%x}", + t.Dst, t.Src, t.Proto, t.Mode, t.Spi, t.Reqid) } // XfrmPolicy represents an ipsec policy. It represents the overlay network diff --git a/libnetwork/Godeps/_workspace/src/github.com/vishvananda/netlink/xfrm_policy_linux.go b/libnetwork/Godeps/_workspace/src/github.com/vishvananda/netlink/xfrm_policy_linux.go index e21a41da07..c3d4e42227 100644 --- a/libnetwork/Godeps/_workspace/src/github.com/vishvananda/netlink/xfrm_policy_linux.go +++ b/libnetwork/Godeps/_workspace/src/github.com/vishvananda/netlink/xfrm_policy_linux.go @@ -22,8 +22,12 @@ func selFromPolicy(sel *nl.XfrmSelector, policy *XfrmPolicy) { sel.Proto = uint8(policy.Proto) sel.Dport = nl.Swap16(uint16(policy.DstPort)) sel.Sport = nl.Swap16(uint16(policy.SrcPort)) - sel.DportMask = ^uint16(0) - sel.SportMask = ^uint16(0) + if sel.Dport != 0 { + sel.DportMask = ^uint16(0) + } + if sel.Sport != 0 { + sel.SportMask = ^uint16(0) + } } // XfrmPolicyAdd will add an xfrm policy to the system. @@ -71,6 +75,7 @@ func (h *Handle) xfrmPolicyAddOrUpdate(policy *XfrmPolicy, nlProto int) error { userTmpl.XfrmId.Daddr.FromIP(tmpl.Dst) userTmpl.Saddr.FromIP(tmpl.Src) userTmpl.XfrmId.Proto = uint8(tmpl.Proto) + userTmpl.XfrmId.Spi = nl.Swap32(uint32(tmpl.Spi)) userTmpl.Mode = uint8(tmpl.Mode) userTmpl.Reqid = uint32(tmpl.Reqid) userTmpl.Aalgos = ^uint32(0) @@ -236,6 +241,7 @@ func parseXfrmPolicy(m []byte, family int) (*XfrmPolicy, error) { resTmpl.Src = tmpl.Saddr.ToIP() resTmpl.Proto = Proto(tmpl.XfrmId.Proto) resTmpl.Mode = Mode(tmpl.Mode) + resTmpl.Spi = int(nl.Swap32(tmpl.XfrmId.Spi)) resTmpl.Reqid = int(tmpl.Reqid) policy.Tmpls = append(policy.Tmpls, resTmpl) }