summaryrefslogtreecommitdiff
path: root/vendor/github.com/vishvananda/netlink/filter_linux.go
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/github.com/vishvananda/netlink/filter_linux.go')
-rw-r--r--vendor/github.com/vishvananda/netlink/filter_linux.go240
1 files changed, 204 insertions, 36 deletions
diff --git a/vendor/github.com/vishvananda/netlink/filter_linux.go b/vendor/github.com/vishvananda/netlink/filter_linux.go
index f0eac6b78..c56f314cd 100644
--- a/vendor/github.com/vishvananda/netlink/filter_linux.go
+++ b/vendor/github.com/vishvananda/netlink/filter_linux.go
@@ -3,10 +3,11 @@ package netlink
import (
"bytes"
"encoding/binary"
+ "encoding/hex"
"errors"
"fmt"
+ "net"
"syscall"
- "unsafe"
"github.com/vishvananda/netlink/nl"
"golang.org/x/sys/unix"
@@ -20,6 +21,35 @@ const (
TC_U32_EAT = nl.TC_U32_EAT
)
+// Sel of the U32 filters that contains multiple TcU32Key. This is the type
+// alias and the frontend representation of nl.TcU32Sel. It is serialized into
+// canonical nl.TcU32Sel with the appropriate endianness.
+type TcU32Sel = nl.TcU32Sel
+
+// TcU32Key contained of Sel in the U32 filters. This is the type alias and the
+// frontend representation of nl.TcU32Key. It is serialized into chanonical
+// nl.TcU32Sel with the appropriate endianness.
+type TcU32Key = nl.TcU32Key
+
+// U32 filters on many packet related properties
+type U32 struct {
+ FilterAttrs
+ ClassId uint32
+ Divisor uint32 // Divisor MUST be power of 2.
+ Hash uint32
+ RedirIndex int
+ Sel *TcU32Sel
+ Actions []Action
+}
+
+func (filter *U32) Attrs() *FilterAttrs {
+ return &filter.FilterAttrs
+}
+
+func (filter *U32) Type() string {
+ return "u32"
+}
+
// 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
@@ -123,8 +153,24 @@ func FilterAdd(filter Filter) error {
// FilterAdd will add a filter to the system.
// Equivalent to: `tc filter add $filter`
func (h *Handle) FilterAdd(filter Filter) error {
+ return h.filterModify(filter, unix.NLM_F_CREATE|unix.NLM_F_EXCL)
+}
+
+// FilterReplace will replace a filter.
+// Equivalent to: `tc filter replace $filter`
+func FilterReplace(filter Filter) error {
+ return pkgHandle.FilterReplace(filter)
+}
+
+// FilterReplace will replace a filter.
+// Equivalent to: `tc filter replace $filter`
+func (h *Handle) FilterReplace(filter Filter) error {
+ return h.filterModify(filter, unix.NLM_F_CREATE)
+}
+
+func (h *Handle) filterModify(filter Filter, flags int) error {
native = nl.NativeEndian()
- req := h.newNetlinkRequest(unix.RTM_NEWTFILTER, unix.NLM_F_CREATE|unix.NLM_F_EXCL|unix.NLM_F_ACK)
+ req := h.newNetlinkRequest(unix.RTM_NEWTFILTER, flags|unix.NLM_F_ACK)
base := filter.Attrs()
msg := &nl.TcMsg{
Family: nl.FAMILY_ALL,
@@ -140,8 +186,7 @@ func (h *Handle) FilterAdd(filter Filter) error {
switch filter := filter.(type) {
case *U32:
- // Convert TcU32Sel into nl.TcU32Sel as it is without copy.
- sel := (*nl.TcU32Sel)(unsafe.Pointer(filter.Sel))
+ sel := filter.Sel
if sel == nil {
// match all
sel = &nl.TcU32Sel{
@@ -168,11 +213,20 @@ func (h *Handle) FilterAdd(filter Filter) error {
}
}
sel.Nkeys = uint8(len(sel.Keys))
- nl.NewRtAttrChild(options, nl.TCA_U32_SEL, sel.Serialize())
+ options.AddRtAttr(nl.TCA_U32_SEL, sel.Serialize())
if filter.ClassId != 0 {
- nl.NewRtAttrChild(options, nl.TCA_U32_CLASSID, nl.Uint32Attr(filter.ClassId))
+ options.AddRtAttr(nl.TCA_U32_CLASSID, nl.Uint32Attr(filter.ClassId))
+ }
+ if filter.Divisor != 0 {
+ if (filter.Divisor-1)&filter.Divisor != 0 {
+ return fmt.Errorf("illegal divisor %d. Must be a power of 2", filter.Divisor)
+ }
+ options.AddRtAttr(nl.TCA_U32_DIVISOR, nl.Uint32Attr(filter.Divisor))
}
- actionsAttr := nl.NewRtAttrChild(options, nl.TCA_U32_ACT, nil)
+ if filter.Hash != 0 {
+ options.AddRtAttr(nl.TCA_U32_HASH, nl.Uint32Attr(filter.Hash))
+ }
+ actionsAttr := options.AddRtAttr(nl.TCA_U32_ACT, nil)
// backwards compatibility
if filter.RedirIndex != 0 {
filter.Actions = append([]Action{NewMirredAction(filter.RedirIndex)}, filter.Actions...)
@@ -184,51 +238,51 @@ func (h *Handle) FilterAdd(filter Filter) error {
if filter.Mask != 0 {
b := make([]byte, 4)
native.PutUint32(b, filter.Mask)
- nl.NewRtAttrChild(options, nl.TCA_FW_MASK, b)
+ options.AddRtAttr(nl.TCA_FW_MASK, b)
}
if filter.InDev != "" {
- nl.NewRtAttrChild(options, nl.TCA_FW_INDEV, nl.ZeroTerminated(filter.InDev))
+ options.AddRtAttr(nl.TCA_FW_INDEV, nl.ZeroTerminated(filter.InDev))
}
if (filter.Police != nl.TcPolice{}) {
- police := nl.NewRtAttrChild(options, nl.TCA_FW_POLICE, nil)
- nl.NewRtAttrChild(police, nl.TCA_POLICE_TBF, filter.Police.Serialize())
+ police := options.AddRtAttr(nl.TCA_FW_POLICE, nil)
+ police.AddRtAttr(nl.TCA_POLICE_TBF, filter.Police.Serialize())
if (filter.Police.Rate != nl.TcRateSpec{}) {
payload := SerializeRtab(filter.Rtab)
- nl.NewRtAttrChild(police, nl.TCA_POLICE_RATE, payload)
+ police.AddRtAttr(nl.TCA_POLICE_RATE, payload)
}
if (filter.Police.PeakRate != nl.TcRateSpec{}) {
payload := SerializeRtab(filter.Ptab)
- nl.NewRtAttrChild(police, nl.TCA_POLICE_PEAKRATE, payload)
+ police.AddRtAttr(nl.TCA_POLICE_PEAKRATE, payload)
}
}
if filter.ClassId != 0 {
b := make([]byte, 4)
native.PutUint32(b, filter.ClassId)
- nl.NewRtAttrChild(options, nl.TCA_FW_CLASSID, b)
+ options.AddRtAttr(nl.TCA_FW_CLASSID, b)
}
case *BpfFilter:
var bpfFlags uint32
if filter.ClassId != 0 {
- nl.NewRtAttrChild(options, nl.TCA_BPF_CLASSID, nl.Uint32Attr(filter.ClassId))
+ options.AddRtAttr(nl.TCA_BPF_CLASSID, nl.Uint32Attr(filter.ClassId))
}
if filter.Fd >= 0 {
- nl.NewRtAttrChild(options, nl.TCA_BPF_FD, nl.Uint32Attr((uint32(filter.Fd))))
+ options.AddRtAttr(nl.TCA_BPF_FD, nl.Uint32Attr((uint32(filter.Fd))))
}
if filter.Name != "" {
- nl.NewRtAttrChild(options, nl.TCA_BPF_NAME, nl.ZeroTerminated(filter.Name))
+ options.AddRtAttr(nl.TCA_BPF_NAME, nl.ZeroTerminated(filter.Name))
}
if filter.DirectAction {
bpfFlags |= nl.TCA_BPF_FLAG_ACT_DIRECT
}
- nl.NewRtAttrChild(options, nl.TCA_BPF_FLAGS, nl.Uint32Attr(bpfFlags))
+ options.AddRtAttr(nl.TCA_BPF_FLAGS, nl.Uint32Attr(bpfFlags))
case *MatchAll:
- actionsAttr := nl.NewRtAttrChild(options, nl.TCA_MATCHALL_ACT, nil)
+ actionsAttr := options.AddRtAttr(nl.TCA_MATCHALL_ACT, nil)
if err := EncodeActions(actionsAttr, filter.Actions); err != nil {
return err
}
if filter.ClassId != 0 {
- nl.NewRtAttrChild(options, nl.TCA_MATCHALL_CLASSID, nl.Uint32Attr(filter.ClassId))
+ options.AddRtAttr(nl.TCA_MATCHALL_CLASSID, nl.Uint32Attr(filter.ClassId))
}
}
@@ -366,34 +420,91 @@ func EncodeActions(attr *nl.RtAttr, actions []Action) error {
default:
return fmt.Errorf("unknown action type %s", action.Type())
case *MirredAction:
- table := nl.NewRtAttrChild(attr, tabIndex, nil)
+ table := attr.AddRtAttr(tabIndex, nil)
tabIndex++
- nl.NewRtAttrChild(table, nl.TCA_ACT_KIND, nl.ZeroTerminated("mirred"))
- aopts := nl.NewRtAttrChild(table, nl.TCA_ACT_OPTIONS, nil)
+ table.AddRtAttr(nl.TCA_ACT_KIND, nl.ZeroTerminated("mirred"))
+ aopts := table.AddRtAttr(nl.TCA_ACT_OPTIONS, nil)
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())
+ aopts.AddRtAttr(nl.TCA_MIRRED_PARMS, mirred.Serialize())
+ case *TunnelKeyAction:
+ table := attr.AddRtAttr(tabIndex, nil)
+ tabIndex++
+ table.AddRtAttr(nl.TCA_ACT_KIND, nl.ZeroTerminated("tunnel_key"))
+ aopts := table.AddRtAttr(nl.TCA_ACT_OPTIONS, nil)
+ tun := nl.TcTunnelKey{
+ Action: int32(action.Action),
+ }
+ toTcGen(action.Attrs(), &tun.TcGen)
+ aopts.AddRtAttr(nl.TCA_TUNNEL_KEY_PARMS, tun.Serialize())
+ if action.Action == TCA_TUNNEL_KEY_SET {
+ aopts.AddRtAttr(nl.TCA_TUNNEL_KEY_ENC_KEY_ID, htonl(action.KeyID))
+ if v4 := action.SrcAddr.To4(); v4 != nil {
+ aopts.AddRtAttr(nl.TCA_TUNNEL_KEY_ENC_IPV4_SRC, v4[:])
+ } else if v6 := action.SrcAddr.To16(); v6 != nil {
+ aopts.AddRtAttr(nl.TCA_TUNNEL_KEY_ENC_IPV6_SRC, v6[:])
+ } else {
+ return fmt.Errorf("invalid src addr %s for tunnel_key action", action.SrcAddr)
+ }
+ if v4 := action.DstAddr.To4(); v4 != nil {
+ aopts.AddRtAttr(nl.TCA_TUNNEL_KEY_ENC_IPV4_DST, v4[:])
+ } else if v6 := action.DstAddr.To16(); v6 != nil {
+ aopts.AddRtAttr(nl.TCA_TUNNEL_KEY_ENC_IPV6_DST, v6[:])
+ } else {
+ return fmt.Errorf("invalid dst addr %s for tunnel_key action", action.DstAddr)
+ }
+ }
+ case *SkbEditAction:
+ table := attr.AddRtAttr(tabIndex, nil)
+ tabIndex++
+ table.AddRtAttr(nl.TCA_ACT_KIND, nl.ZeroTerminated("skbedit"))
+ aopts := table.AddRtAttr(nl.TCA_ACT_OPTIONS, nil)
+ skbedit := nl.TcSkbEdit{}
+ toTcGen(action.Attrs(), &skbedit.TcGen)
+ aopts.AddRtAttr(nl.TCA_SKBEDIT_PARMS, skbedit.Serialize())
+ if action.QueueMapping != nil {
+ aopts.AddRtAttr(nl.TCA_SKBEDIT_QUEUE_MAPPING, nl.Uint16Attr(*action.QueueMapping))
+ }
+ if action.Priority != nil {
+ aopts.AddRtAttr(nl.TCA_SKBEDIT_PRIORITY, nl.Uint32Attr(*action.Priority))
+ }
+ if action.PType != nil {
+ aopts.AddRtAttr(nl.TCA_SKBEDIT_PTYPE, nl.Uint16Attr(*action.PType))
+ }
+ if action.Mark != nil {
+ aopts.AddRtAttr(nl.TCA_SKBEDIT_MARK, nl.Uint32Attr(*action.Mark))
+ }
+ case *ConnmarkAction:
+ table := attr.AddRtAttr(tabIndex, nil)
+ tabIndex++
+ table.AddRtAttr(nl.TCA_ACT_KIND, nl.ZeroTerminated("connmark"))
+ aopts := table.AddRtAttr(nl.TCA_ACT_OPTIONS, nil)
+ connmark := nl.TcConnmark{
+ Zone: action.Zone,
+ }
+ toTcGen(action.Attrs(), &connmark.TcGen)
+ aopts.AddRtAttr(nl.TCA_CONNMARK_PARMS, connmark.Serialize())
case *BpfAction:
- table := nl.NewRtAttrChild(attr, tabIndex, nil)
+ table := attr.AddRtAttr(tabIndex, nil)
tabIndex++
- nl.NewRtAttrChild(table, nl.TCA_ACT_KIND, nl.ZeroTerminated("bpf"))
- aopts := nl.NewRtAttrChild(table, nl.TCA_ACT_OPTIONS, nil)
+ table.AddRtAttr(nl.TCA_ACT_KIND, nl.ZeroTerminated("bpf"))
+ aopts := table.AddRtAttr(nl.TCA_ACT_OPTIONS, nil)
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))
+ aopts.AddRtAttr(nl.TCA_ACT_BPF_PARMS, gen.Serialize())
+ aopts.AddRtAttr(nl.TCA_ACT_BPF_FD, nl.Uint32Attr(uint32(action.Fd)))
+ aopts.AddRtAttr(nl.TCA_ACT_BPF_NAME, nl.ZeroTerminated(action.Name))
case *GenericAction:
- table := nl.NewRtAttrChild(attr, tabIndex, nil)
+ table := attr.AddRtAttr(tabIndex, nil)
tabIndex++
- nl.NewRtAttrChild(table, nl.TCA_ACT_KIND, nl.ZeroTerminated("gact"))
- aopts := nl.NewRtAttrChild(table, nl.TCA_ACT_OPTIONS, nil)
+ table.AddRtAttr(nl.TCA_ACT_KIND, nl.ZeroTerminated("gact"))
+ aopts := table.AddRtAttr(nl.TCA_ACT_OPTIONS, nil)
gen := nl.TcGen{}
toTcGen(action.Attrs(), &gen)
- nl.NewRtAttrChild(aopts, nl.TCA_GACT_PARMS, gen.Serialize())
+ aopts.AddRtAttr(nl.TCA_GACT_PARMS, gen.Serialize())
}
}
return nil
@@ -419,8 +530,14 @@ func parseActions(tables []syscall.NetlinkRouteAttr) ([]Action, error) {
action = &MirredAction{}
case "bpf":
action = &BpfAction{}
+ case "connmark":
+ action = &ConnmarkAction{}
case "gact":
action = &GenericAction{}
+ case "tunnel_key":
+ action = &TunnelKeyAction{}
+ case "skbedit":
+ action = &SkbEditAction{}
default:
break nextattr
}
@@ -435,11 +552,46 @@ func parseActions(tables []syscall.NetlinkRouteAttr) ([]Action, error) {
switch adatum.Attr.Type {
case nl.TCA_MIRRED_PARMS:
mirred := *nl.DeserializeTcMirred(adatum.Value)
- toAttrs(&mirred.TcGen, action.Attrs())
action.(*MirredAction).ActionAttrs = ActionAttrs{}
+ toAttrs(&mirred.TcGen, action.Attrs())
action.(*MirredAction).Ifindex = int(mirred.Ifindex)
action.(*MirredAction).MirredAction = MirredAct(mirred.Eaction)
}
+ case "tunnel_key":
+ switch adatum.Attr.Type {
+ case nl.TCA_TUNNEL_KEY_PARMS:
+ tun := *nl.DeserializeTunnelKey(adatum.Value)
+ action.(*TunnelKeyAction).ActionAttrs = ActionAttrs{}
+ toAttrs(&tun.TcGen, action.Attrs())
+ action.(*TunnelKeyAction).Action = TunnelKeyAct(tun.Action)
+ case nl.TCA_TUNNEL_KEY_ENC_KEY_ID:
+ action.(*TunnelKeyAction).KeyID = networkOrder.Uint32(adatum.Value[0:4])
+ case nl.TCA_TUNNEL_KEY_ENC_IPV6_SRC:
+ case nl.TCA_TUNNEL_KEY_ENC_IPV4_SRC:
+ action.(*TunnelKeyAction).SrcAddr = net.IP(adatum.Value[:])
+ case nl.TCA_TUNNEL_KEY_ENC_IPV6_DST:
+ case nl.TCA_TUNNEL_KEY_ENC_IPV4_DST:
+ action.(*TunnelKeyAction).DstAddr = net.IP(adatum.Value[:])
+ }
+ case "skbedit":
+ switch adatum.Attr.Type {
+ case nl.TCA_SKBEDIT_PARMS:
+ skbedit := *nl.DeserializeSkbEdit(adatum.Value)
+ action.(*SkbEditAction).ActionAttrs = ActionAttrs{}
+ toAttrs(&skbedit.TcGen, action.Attrs())
+ case nl.TCA_SKBEDIT_MARK:
+ mark := native.Uint32(adatum.Value[0:4])
+ action.(*SkbEditAction).Mark = &mark
+ case nl.TCA_SKBEDIT_PRIORITY:
+ priority := native.Uint32(adatum.Value[0:4])
+ action.(*SkbEditAction).Priority = &priority
+ case nl.TCA_SKBEDIT_PTYPE:
+ ptype := native.Uint16(adatum.Value[0:2])
+ action.(*SkbEditAction).PType = &ptype
+ case nl.TCA_SKBEDIT_QUEUE_MAPPING:
+ mapping := native.Uint16(adatum.Value[0:2])
+ action.(*SkbEditAction).QueueMapping = &mapping
+ }
case "bpf":
switch adatum.Attr.Type {
case nl.TCA_ACT_BPF_PARMS:
@@ -450,6 +602,14 @@ func parseActions(tables []syscall.NetlinkRouteAttr) ([]Action, error) {
case nl.TCA_ACT_BPF_NAME:
action.(*BpfAction).Name = string(adatum.Value[:len(adatum.Value)-1])
}
+ case "connmark":
+ switch adatum.Attr.Type {
+ case nl.TCA_CONNMARK_PARMS:
+ connmark := *nl.DeserializeTcConnmark(adatum.Value)
+ action.(*ConnmarkAction).ActionAttrs = ActionAttrs{}
+ toAttrs(&connmark.TcGen, action.Attrs())
+ action.(*ConnmarkAction).Zone = connmark.Zone
+ }
case "gact":
switch adatum.Attr.Type {
case nl.TCA_GACT_PARMS:
@@ -474,7 +634,7 @@ func parseU32Data(filter Filter, data []syscall.NetlinkRouteAttr) (bool, error)
case nl.TCA_U32_SEL:
detailed = true
sel := nl.DeserializeTcU32Sel(datum.Value)
- u32.Sel = (*TcU32Sel)(unsafe.Pointer(sel))
+ u32.Sel = sel
if native != networkOrder {
// Handle the endianness of attributes
u32.Sel.Offmask = native.Uint16(htons(sel.Offmask))
@@ -500,6 +660,10 @@ func parseU32Data(filter Filter, data []syscall.NetlinkRouteAttr) (bool, error)
}
case nl.TCA_U32_CLASSID:
u32.ClassId = native.Uint32(datum.Value)
+ case nl.TCA_U32_DIVISOR:
+ u32.Divisor = native.Uint32(datum.Value)
+ case nl.TCA_U32_HASH:
+ u32.Hash = native.Uint32(datum.Value)
}
}
return detailed, nil
@@ -551,6 +715,10 @@ func parseBpfData(filter Filter, data []syscall.NetlinkRouteAttr) (bool, error)
if (flags & nl.TCA_BPF_FLAG_ACT_DIRECT) != 0 {
bpf.DirectAction = true
}
+ case nl.TCA_BPF_ID:
+ bpf.Id = int(native.Uint32(datum.Value[0:4]))
+ case nl.TCA_BPF_TAG:
+ bpf.Tag = hex.EncodeToString(datum.Value[:len(datum.Value)-1])
}
}
return detailed, nil